diff options
585 files changed, 27835 insertions, 12871 deletions
diff --git a/TEST_MAPPING b/TEST_MAPPING index 07d16f7a4d..a4a22a0f1d 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -22,5 +22,21 @@ { "name": "SurfaceFlinger_test" } + ], + "postsubmit": [ + { + "name": "SurfaceFlinger_test", + "keywords": [ "primary-device" ], + "options": [ + // TODO(b/328119950) Known to be broken. + { + "exclude-filter": "LayerCallbackTest#SetNullBuffer" + }, + // TODO(b/398306512) Flaky on real device. + { + "exclude-filter": "LayerRenderTypeTransactionTests/LayerRenderTypeTransactionTest#SetRelativeZBasic_BufferQueue/*" + } + ] + } ] } diff --git a/aidl/binder/android/os/PersistableBundle.aidl b/aidl/binder/android/os/PersistableBundle.aidl index 248e9738df..9b11109262 100644 --- a/aidl/binder/android/os/PersistableBundle.aidl +++ b/aidl/binder/android/os/PersistableBundle.aidl @@ -17,4 +17,4 @@ package android.os; -@JavaOnlyStableParcelable @NdkOnlyStableParcelable parcelable PersistableBundle cpp_header "binder/PersistableBundle.h" ndk_header "android/persistable_bundle_aidl.h"; +@JavaOnlyStableParcelable @NdkOnlyStableParcelable @RustOnlyStableParcelable parcelable PersistableBundle cpp_header "binder/PersistableBundle.h" ndk_header "android/persistable_bundle_aidl.h" rust_type "binder::PersistableBundle"; diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp index 94590876b7..fdb032b285 100644 --- a/cmds/dumpstate/Android.bp +++ b/cmds/dumpstate/Android.bp @@ -83,14 +83,16 @@ cc_defaults { "aconfig_lib_cc_static_link.defaults", "dumpstate_cflag_defaults", ], + // See README.md: "Dumpstate philosophy: exec not link" + // Do not add things here - keep dumpstate as simple as possible and exec where possible. shared_libs: [ "android.hardware.dumpstate@1.0", "android.hardware.dumpstate@1.1", "android.hardware.dumpstate-V1-ndk", "libziparchive", "libbase", - "libbinder", - "libbinder_ndk", + "libbinder", // BAD: dumpstate should not link code directly, should only exec binaries + "libbinder_ndk", // BAD: dumpstate should not link code directly, should only exec binaries "libcrypto", "libcutils", "libdebuggerd_client", @@ -98,11 +100,11 @@ cc_defaults { "libdumpstateutil", "libdumputils", "libhardware_legacy", - "libhidlbase", + "libhidlbase", // BAD: dumpstate should not link code directly, should only exec binaries "liblog", "libutils", - "libvintf", - "libbinderdebug", + "libvintf", // BAD: dumpstate should not link code directly, should only exec binaries + "libbinderdebug", // BAD: dumpstate should not link code directly, should only exec binaries "packagemanager_aidl-cpp", "server_configurable_flags", "device_policy_aconfig_flags_c_lib", @@ -115,6 +117,7 @@ cc_defaults { "libdumpsys", "libserviceutils", "android.tracing.flags_c_lib", + "perfetto_flags_c_lib", ], } diff --git a/cmds/dumpstate/README.md b/cmds/dumpstate/README.md index 26dabbbcef..3ab971a7e4 100644 --- a/cmds/dumpstate/README.md +++ b/cmds/dumpstate/README.md @@ -21,6 +21,18 @@ Example: mmm -j frameworks/native/cmds/dumpstate device/acme/secret_device/dumpstate/ hardware/interfaces/dumpstate ``` +## Dumpstate philosophy: exec not link + +Never link code directly into dumpstate. Dumpstate should execute many +binaries and collect the results. In general, code should fail hard fail fast, +but dumpstate is the last to solve many Android bugs. Oftentimes, failures +in core Android infrastructure or tools are issues that cause problems in +bugreport directly, so bugreport should not rely on these tools working. +We want dumpstate to have as minimal of code loaded in process so that +only that core subset needs to be bugfree for bugreport to work. Even if +many pieces of Android break, that should not prevent dumpstate from +working. + ## To build, deploy, and take a bugreport ``` diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index fcc6108f5f..9e3e2b0468 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -57,6 +57,7 @@ #include <log/log_read.h> #include <math.h> #include <openssl/sha.h> +#include <perfetto_flags.h> #include <poll.h> #include <private/android_filesystem_config.h> #include <private/android_logger.h> @@ -128,6 +129,9 @@ using android::os::dumpstate::PropertiesHelper; using android::os::dumpstate::TaskQueue; using android::os::dumpstate::WaitForTask; +// BAD - See README.md: "Dumpstate philosophy: exec not link" +// Do not add more complicated variables here, prefer to execute only. Don't link more code here. + // Keep in sync with // frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java static const int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds @@ -187,11 +191,10 @@ void add_mountinfo(); #define SNAPSHOTCTL_LOG_DIR "/data/misc/snapshotctl_log" #define LINKERCONFIG_DIR "/linkerconfig" #define PACKAGE_DEX_USE_LIST "/data/system/package-dex-usage.list" -#define SYSTEM_TRACE_SNAPSHOT "/data/misc/perfetto-traces/bugreport/systrace.pftrace" +#define SYSTEM_TRACE_DIR "/data/misc/perfetto-traces/bugreport" #define CGROUPFS_DIR "/sys/fs/cgroup" #define SDK_EXT_INFO "/apex/com.android.sdkext/bin/derive_sdk" #define DROPBOX_DIR "/data/system/dropbox" -#define PRINT_FLAGS "/system/bin/printflags" #define UWB_LOG_DIR "/data/misc/apexdata/com.android.uwb/log" // TODO(narayan): Since this information has to be kept in sync @@ -357,6 +360,31 @@ static bool CopyFileToFile(const std::string& input_file, const std::string& out return CopyFileToFd(input_file, out_fd.get()); } +template <typename Func> +size_t ForEachTrace(Func func) { + std::unique_ptr<DIR, decltype(&closedir)> traces_dir(opendir(SYSTEM_TRACE_DIR), closedir); + + if (traces_dir == nullptr) { + MYLOGW("Unable to open directory %s: %s\n", SYSTEM_TRACE_DIR, strerror(errno)); + return 0; + } + + size_t traces_found = 0; + struct dirent* entry = nullptr; + while ((entry = readdir(traces_dir.get()))) { + if (entry->d_type != DT_REG) { + continue; + } + std::string trace_path = std::string(SYSTEM_TRACE_DIR) + "/" + entry->d_name; + if (access(trace_path.c_str(), F_OK) != 0) { + continue; + } + ++traces_found; + func(trace_path); + } + return traces_found; +} + } // namespace } // namespace os } // namespace android @@ -1099,20 +1127,16 @@ static void MaybeAddSystemTraceToZip() { // This function copies into the .zip the system trace that was snapshotted // by the early call to MaybeSnapshotSystemTraceAsync(), if any background // tracing was happening. - bool system_trace_exists = access(SYSTEM_TRACE_SNAPSHOT, F_OK) == 0; - if (!system_trace_exists) { - // No background trace was happening at the time MaybeSnapshotSystemTraceAsync() was invoked - if (!PropertiesHelper::IsUserBuild()) { - MYLOGI( - "No system traces found. Check for previously uploaded traces by looking for " - "go/trace-uuid in logcat") - } - return; + size_t traces_found = android::os::ForEachTrace([&](const std::string& trace_path) { + ds.AddZipEntry(ZIP_ROOT_DIR + trace_path, trace_path); + android::os::UnlinkAndLogOnError(trace_path); + }); + + if (traces_found == 0 && !PropertiesHelper::IsUserBuild()) { + MYLOGI( + "No system traces found. Check for previously uploaded traces by looking for " + "go/trace-uuid in logcat") } - ds.AddZipEntry( - ZIP_ROOT_DIR + SYSTEM_TRACE_SNAPSHOT, - SYSTEM_TRACE_SNAPSHOT); - android::os::UnlinkAndLogOnError(SYSTEM_TRACE_SNAPSHOT); } static void DumpVisibleWindowViews() { @@ -1273,6 +1297,8 @@ static void DumpKernelMemoryAllocations() { } } +// BAD - See README.md: "Dumpstate philosophy: exec not link" +// This should all be moved into a separate binary rather than have complex logic here. static Dumpstate::RunStatus RunDumpsysTextByPriority(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { @@ -1353,6 +1379,8 @@ static Dumpstate::RunStatus RunDumpsysTextNormalPriority(const std::string& titl service_timeout); } +// BAD - See README.md: "Dumpstate philosophy: exec not link" +// This should all be moved into a separate binary rather than have complex logic here. static Dumpstate::RunStatus RunDumpsysProto(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { @@ -1434,6 +1462,8 @@ static Dumpstate::RunStatus RunDumpsysNormal() { * Dumpstate can pick up later and output to the bugreport. Using STDOUT_FILENO * if it's not running in the parallel task. */ +// BAD - See README.md: "Dumpstate philosophy: exec not link" +// This should all be moved into a separate binary rather than have complex logic here. static void DumpHals(int out_fd = STDOUT_FILENO) { RunCommand("HARDWARE HALS", {"lshal", "--all", "--types=all"}, CommandOptions::WithTimeout(10).AsRootIfAvailable().Build(), @@ -1490,6 +1520,9 @@ static void DumpHals(int out_fd = STDOUT_FILENO) { } } +// BAD - See README.md: "Dumpstate philosophy: exec not link" +// This should all be moved into a separate binary rather than have complex logic here. +// // Dump all of the files that make up the vendor interface. // See the files listed in dumpFileList() for the latest list of files. static void DumpVintf() { @@ -1519,6 +1552,8 @@ static void DumpExternalFragmentationInfo() { printf("------ EXTERNAL FRAGMENTATION INFO ------\n"); std::ifstream ifs("/proc/buddyinfo"); auto unusable_index_regex = std::regex{"Node\\s+([0-9]+),\\s+zone\\s+(\\S+)\\s+(.*)"}; + // BAD - See README.md: "Dumpstate philosophy: exec not link" + // This should all be moved into a separate binary rather than have complex logic here. for (std::string line; std::getline(ifs, line);) { std::smatch match_results; if (std::regex_match(line, match_results, unusable_index_regex)) { @@ -1809,12 +1844,8 @@ Dumpstate::RunStatus Dumpstate::dumpstate() { DumpFile("PRODUCT BUILD-TIME RELEASE FLAGS", "/product/etc/build_flags.json"); DumpFile("VENDOR BUILD-TIME RELEASE FLAGS", "/vendor/etc/build_flags.json"); - RunCommand("ACONFIG FLAGS", {PRINT_FLAGS}, - CommandOptions::WithTimeout(10).Always().DropRoot().Build()); RunCommand("ACONFIG FLAGS DUMP", {AFLAGS, "list"}, CommandOptions::WithTimeout(10).Always().AsRootIfAvailable().Build()); - RunCommand("WHICH ACONFIG FLAG STORAGE", {AFLAGS, "which-backing"}, - CommandOptions::WithTimeout(10).Always().AsRootIfAvailable().Build()); RunCommand("STORAGED IO INFO", {"storaged", "-u", "-p"}); @@ -2464,6 +2495,8 @@ static dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode GetDumpstateHalModeAi return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::DEFAULT; } +// BAD - See README.md: "Dumpstate philosophy: exec not link" +// This should all be moved into a separate binary rather than have complex logic here. static void DoDumpstateBoardHidl( const sp<dumpstate_hal_hidl_1_0::IDumpstateDevice> dumpstate_hal_1_0, const std::vector<::ndk::ScopedFileDescriptor>& dumpstate_fds, @@ -3401,8 +3434,8 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, // duration is logged into MYLOG instead. PrintHeader(); - bool system_trace_exists = access(SYSTEM_TRACE_SNAPSHOT, F_OK) == 0; - if (options_->use_predumped_ui_data && !system_trace_exists) { + size_t trace_count = android::os::ForEachTrace([](const std::string&) {}); + if (options_->use_predumped_ui_data && trace_count == 0) { MYLOGW("Ignoring 'use predumped data' flag because no predumped data is available"); options_->use_predumped_ui_data = false; } @@ -3549,20 +3582,24 @@ std::future<std::string> Dumpstate::MaybeSnapshotSystemTraceAsync() { } // If a stale file exists already, remove it. - unlink(SYSTEM_TRACE_SNAPSHOT); + android::os::ForEachTrace([&](const std::string& trace_path) { unlink(trace_path.c_str()); }); MYLOGI("Launching async '%s'", SERIALIZE_PERFETTO_TRACE_TASK.c_str()) + return std::async( std::launch::async, [this, outPath = std::move(outPath), outFd = std::move(outFd)] { - // If a background system trace is happening and is marked as "suitable for - // bugreport" (i.e. bugreport_score > 0 in the trace config), this command - // will stop it and serialize into SYSTEM_TRACE_SNAPSHOT. In the (likely) - // case that no trace is ongoing, this command is a no-op. + // If one or more background system traces are happening and are marked as + // "suitable for bugreport" (bugreport_score > 0 in the trace config), this command + // will snapshot them into SYSTEM_TRACE_DIR. + // In the (likely) case that no trace is ongoing, this command is a no-op. // Note: this should not be enqueued as we need to freeze the trace before // dumpstate starts. Otherwise the trace ring buffers will contain mostly // the dumpstate's own activity which is irrelevant. + const char* cmd_arg = perfetto::flags::save_all_traces_in_bugreport() + ? "--save-all-for-bugreport" + : "--save-for-bugreport"; RunCommand( - SERIALIZE_PERFETTO_TRACE_TASK, {"perfetto", "--save-for-bugreport"}, + SERIALIZE_PERFETTO_TRACE_TASK, {"perfetto", cmd_arg}, CommandOptions::WithTimeout(30).DropRoot().CloseAllFileDescriptorsOnExec().Build(), false, outFd); // MaybeAddSystemTraceToZip() will take care of copying the trace in the zip diff --git a/cmds/dumpstate/dumpstate_smoke_test.xml b/cmds/dumpstate/dumpstate_smoke_test.xml index 0aff200dd2..7e3307d292 100644 --- a/cmds/dumpstate/dumpstate_smoke_test.xml +++ b/cmds/dumpstate/dumpstate_smoke_test.xml @@ -22,7 +22,9 @@ <option name="cleanup" value="true" /> <option name="push" value="dumpstate_smoke_test->/data/local/tmp/dumpstate_smoke_test" /> </target_preparer> - + <target_preparer class="com.android.tradefed.targetprep.FeatureFlagTargetPreparer"> + <option name="flag-value" value="perfetto/perfetto.flags.save_all_traces_in_bugreport=true" /> + </target_preparer> <test class="com.android.tradefed.testtype.GTest" > <option name="native-test-device-path" value="/data/local/tmp" /> <option name="module-name" value="dumpstate_smoke_test" /> diff --git a/cmds/dumpstate/res/default_screenshot.png b/cmds/dumpstate/res/default_screenshot.png Binary files differindex 10f36aa52b..1e14306504 100644 --- a/cmds/dumpstate/res/default_screenshot.png +++ b/cmds/dumpstate/res/default_screenshot.png diff --git a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp index a29923a4c1..c72847c053 100644 --- a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp +++ b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp @@ -24,8 +24,10 @@ #include <gmock/gmock.h> #include <gtest/gtest.h> #include <libgen.h> +#include <signal.h> #include <ziparchive/zip_archive.h> +#include <cstdio> #include <fstream> #include <regex> @@ -603,6 +605,93 @@ TEST_F(DumpstateBinderTest, SimultaneousBugreportsNotAllowed) { listener1->getErrorCode() == IDumpstateListener::BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT); } +class DumpstateTracingTest : public Test { + protected: + void TearDown() override { + for (int pid : bg_process_pids) { + kill(pid, SIGKILL); + } + } + + void StartTracing(const std::string& config) { + // Write the perfetto config into a file. + const int id = static_cast<int>(bg_process_pids.size()); + char cfg[64]; + snprintf(cfg, sizeof(cfg), "/data/misc/perfetto-configs/br-%d", id); + unlink(cfg); // Remove the config file if it exists already. + FILE* f = fopen(cfg, "w"); + ASSERT_NE(f, nullptr); + fputs(config.c_str(), f); + fclose(f); + + // Invoke perfetto to start tracing. + char cmd[255]; + snprintf(cmd, sizeof(cmd), "perfetto --background-wait --txt -o /dev/null -c %s", cfg); + FILE* proc = popen(cmd, "r"); + ASSERT_NE(proc, nullptr); + + // Read back the PID of the background process. We will use it to kill + // all tracing sessions when the test ends or fails. + char pid_str[32]{}; + ASSERT_NE(fgets(pid_str, sizeof(pid_str), proc), nullptr); + int pid = atoi(pid_str); + bg_process_pids.push_back(pid); + + pclose(proc); + unlink(cfg); + } + + std::vector<int> bg_process_pids; +}; + +TEST_F(DumpstateTracingTest, ManyTracesInBugreport) { + // Note the trace duration is irrelevant and is only an upper bound. + // Tracing is stopped as soon as the bugreport.zip creation ends. + StartTracing(R"( +buffers { size_kb: 4096 } +data_sources { + config { + name: "linux.ftrace" + } +} + +duration_ms: 120000 +bugreport_filename: "sys.pftrace" +bugreport_score: 100 +)"); + + StartTracing(R"( +buffers { size_kb: 4096 } +data_sources { + config { + name: "linux.ftrace" + } +} + +duration_ms: 120000 +bugreport_score: 50 +bugreport_filename: "mem.pftrace" +)"); + + ZippedBugreportGenerationTest::GenerateBugreport(); + std::string zip_path = ZippedBugreportGenerationTest::getZipFilePath(); + ZipArchiveHandle handle; + ASSERT_EQ(OpenArchive(zip_path.c_str(), &handle), 0); + + const char* kExpectedEntries[]{ + "FS/data/misc/perfetto-traces/bugreport/sys.pftrace", + "FS/data/misc/perfetto-traces/bugreport/mem.pftrace", + }; + + // Check that the bugreport contains both traces. + for (const char* file_path : kExpectedEntries) { + ZipEntry entry{}; + GetEntry(handle, file_path, &entry); + EXPECT_GT(entry.uncompressed_length, 100); + } + CloseArchive(handle); +} + } // namespace dumpstate } // namespace os } // namespace android diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp index 77e732805e..6e6d27d463 100644 --- a/cmds/flatland/GLHelper.cpp +++ b/cmds/flatland/GLHelper.cpp @@ -202,26 +202,13 @@ bool GLHelper::getShaderProgram(const char* name, GLuint* outPgm) { } bool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h, - sp<GLConsumer>* glConsumer, EGLSurface* surface) { -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) - sp<GLConsumer> glc = new GLConsumer(name, GL_TEXTURE_EXTERNAL_OES, false, true); + sp<GLConsumer>* glConsumer, EGLSurface* surface) { + auto [glc, surf] = GLConsumer::create(name, GL_TEXTURE_EXTERNAL_OES, false, true); glc->setDefaultBufferSize(w, h); - glc->getSurface()->setMaxDequeuedBufferCount(2); glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER); + surf->setMaxDequeuedBufferCount(2); + sp<ANativeWindow> anw = surf; - sp<ANativeWindow> anw = glc->getSurface(); -#else - sp<IGraphicBufferProducer> producer; - sp<IGraphicBufferConsumer> consumer; - BufferQueue::createBufferQueue(&producer, &consumer); - sp<GLConsumer> glc = new GLConsumer(consumer, name, - GL_TEXTURE_EXTERNAL_OES, false, true); - glc->setDefaultBufferSize(w, h); - producer->setMaxDequeuedBufferCount(2); - glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER); - - sp<ANativeWindow> anw = new Surface(producer); -#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), nullptr); if (s == EGL_NO_SURFACE) { fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError()); diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp index 6d14d568a4..277300d20f 100644 --- a/cmds/flatland/Main.cpp +++ b/cmds/flatland/Main.cpp @@ -772,8 +772,8 @@ int main(int argc, char** argv) { break; case 'i': - displayId = DisplayId::fromValue<PhysicalDisplayId>(atoll(optarg)); - if (!displayId) { + displayId = PhysicalDisplayId::fromValue(atoll(optarg)); + if (std::find(ids.begin(), ids.end(), displayId) == ids.end()) { fprintf(stderr, "Invalid display ID: %s.\n", optarg); exit(4); } diff --git a/cmds/idlcli/Android.bp b/cmds/idlcli/Android.bp index 36dcbca0a3..b87ef2dc36 100644 --- a/cmds/idlcli/Android.bp +++ b/cmds/idlcli/Android.bp @@ -25,13 +25,8 @@ cc_defaults { name: "idlcli-defaults", shared_libs: [ "android.hardware.vibrator-V3-ndk", - "android.hardware.vibrator@1.0", - "android.hardware.vibrator@1.1", - "android.hardware.vibrator@1.2", - "android.hardware.vibrator@1.3", "libbase", "libbinder_ndk", - "libhidlbase", "liblog", "libutils", ], diff --git a/cmds/idlcli/utils.h b/cmds/idlcli/utils.h index 262f2e50b6..dc52c57987 100644 --- a/cmds/idlcli/utils.h +++ b/cmds/idlcli/utils.h @@ -18,7 +18,6 @@ #define FRAMEWORK_NATIVE_CMDS_IDLCLI_UTILS_H_ #include <android/binder_enums.h> -#include <hidl/HidlSupport.h> #include <iomanip> #include <iostream> diff --git a/cmds/idlcli/vibrator.h b/cmds/idlcli/vibrator.h index b9434950f6..1a9993e5e7 100644 --- a/cmds/idlcli/vibrator.h +++ b/cmds/idlcli/vibrator.h @@ -22,102 +22,30 @@ #include <aidl/android/hardware/vibrator/IVibratorManager.h> #include <android/binder_manager.h> #include <android/binder_process.h> -#include <android/hardware/vibrator/1.3/IVibrator.h> #include "IdlCli.h" #include "utils.h" namespace android { -using hardware::Return; +using ::aidl::android::hardware::vibrator::IVibrator; using idlcli::IdlCli; -static constexpr int NUM_TRIES = 2; - -// Creates a Return<R> with STATUS::EX_NULL_POINTER. -template <class R> -inline R NullptrStatus() { - using ::android::hardware::Status; - return Status::fromExceptionCode(Status::EX_NULL_POINTER); -} - -template <> -inline ndk::ScopedAStatus NullptrStatus() { - return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_NULL_POINTER)); -} - -template <typename I> inline auto getService(std::string name) { - const auto instance = std::string() + I::descriptor + "/" + name; + const auto instance = std::string() + IVibrator::descriptor + "/" + name; auto vibBinder = ndk::SpAIBinder(AServiceManager_checkService(instance.c_str())); - return I::fromBinder(vibBinder); -} - -template <> -inline auto getService<android::hardware::vibrator::V1_0::IVibrator>(std::string name) { - return android::hardware::vibrator::V1_0::IVibrator::getService(name); -} - -template <> -inline auto getService<android::hardware::vibrator::V1_1::IVibrator>(std::string name) { - return android::hardware::vibrator::V1_1::IVibrator::getService(name); -} - -template <> -inline auto getService<android::hardware::vibrator::V1_2::IVibrator>(std::string name) { - return android::hardware::vibrator::V1_2::IVibrator::getService(name); -} - -template <> -inline auto getService<android::hardware::vibrator::V1_3::IVibrator>(std::string name) { - return android::hardware::vibrator::V1_3::IVibrator::getService(name); + return IVibrator::fromBinder(vibBinder); } -template <typename I> -using shared_ptr = std::invoke_result_t<decltype(getService<I>)&, std::string>; - -template <typename I> -class HalWrapper { -public: - static std::unique_ptr<HalWrapper> Create() { - // Assume that if getService returns a nullptr, HAL is not available on the - // device. - const auto name = IdlCli::Get().getName(); - auto hal = getService<I>(name.empty() ? "default" : name); - return hal ? std::unique_ptr<HalWrapper>(new HalWrapper(std::move(hal))) : nullptr; - } - - template <class R, class... Args0, class... Args1> - R call(R (I::*fn)(Args0...), Args1&&... args1) { - return (*mHal.*fn)(std::forward<Args1>(args1)...); - } - -private: - HalWrapper(shared_ptr<I>&& hal) : mHal(std::move(hal)) {} - -private: - shared_ptr<I> mHal; -}; - -template <typename I> static auto getHal() { - static auto sHalWrapper = HalWrapper<I>::Create(); - return sHalWrapper.get(); -} - -template <class R, class I, class... Args0, class... Args1> -R halCall(R (I::*fn)(Args0...), Args1&&... args1) { - auto hal = getHal<I>(); - return hal ? hal->call(fn, std::forward<Args1>(args1)...) : NullptrStatus<R>(); + // Assume that if getService returns a nullptr, HAL is not available on the device. + const auto name = IdlCli::Get().getName(); + return getService(name.empty() ? "default" : name); } namespace idlcli { namespace vibrator { -namespace V1_0 = ::android::hardware::vibrator::V1_0; -namespace V1_1 = ::android::hardware::vibrator::V1_1; -namespace V1_2 = ::android::hardware::vibrator::V1_2; -namespace V1_3 = ::android::hardware::vibrator::V1_3; namespace aidl = ::aidl::android::hardware::vibrator; class VibratorCallback : public aidl::BnVibratorCallback { diff --git a/cmds/idlcli/vibrator/CommandAlwaysOnDisable.cpp b/cmds/idlcli/vibrator/CommandAlwaysOnDisable.cpp index 9afa300c2b..cae690945c 100644 --- a/cmds/idlcli/vibrator/CommandAlwaysOnDisable.cpp +++ b/cmds/idlcli/vibrator/CommandAlwaysOnDisable.cpp @@ -51,21 +51,17 @@ class CommandAlwaysOnDisable : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::alwaysOnDisable, mId); - - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + auto status = hal->alwaysOnDisable(mId); + + std::cout << "Status: " << status.getDescription() << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } int32_t mId; diff --git a/cmds/idlcli/vibrator/CommandAlwaysOnEnable.cpp b/cmds/idlcli/vibrator/CommandAlwaysOnEnable.cpp index bb7f9f284a..410ca52068 100644 --- a/cmds/idlcli/vibrator/CommandAlwaysOnEnable.cpp +++ b/cmds/idlcli/vibrator/CommandAlwaysOnEnable.cpp @@ -72,21 +72,17 @@ class CommandAlwaysOnEnable : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::alwaysOnEnable, mId, mEffect, mStrength); - - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + auto status = hal->alwaysOnEnable(mId, mEffect, mStrength); + + std::cout << "Status: " << status.getDescription() << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } int32_t mId; diff --git a/cmds/idlcli/vibrator/CommandCompose.cpp b/cmds/idlcli/vibrator/CommandCompose.cpp index eb9008b68e..41acb98a95 100644 --- a/cmds/idlcli/vibrator/CommandCompose.cpp +++ b/cmds/idlcli/vibrator/CommandCompose.cpp @@ -89,7 +89,7 @@ class CommandCompose : public Command { } Status doMain(Args && /*args*/) override { - auto hal = getHal<aidl::IVibrator>(); + auto hal = getHal(); if (!hal) { return UNAVAILABLE; @@ -104,7 +104,7 @@ class CommandCompose : public Command { callback = ndk::SharedRefBase::make<VibratorCallback>(); } - auto status = hal->call(&aidl::IVibrator::compose, mComposite, callback); + auto status = hal->compose(mComposite, callback); if (status.isOk() && callback) { callback->waitForComplete(); diff --git a/cmds/idlcli/vibrator/CommandComposePwle.cpp b/cmds/idlcli/vibrator/CommandComposePwle.cpp index b8308ce16f..5f6bf8677e 100644 --- a/cmds/idlcli/vibrator/CommandComposePwle.cpp +++ b/cmds/idlcli/vibrator/CommandComposePwle.cpp @@ -163,7 +163,7 @@ class CommandComposePwle : public Command { } Status doMain(Args && /*args*/) override { - auto hal = getHal<aidl::IVibrator>(); + auto hal = getHal(); if (!hal) { return UNAVAILABLE; @@ -178,7 +178,7 @@ class CommandComposePwle : public Command { callback = ndk::SharedRefBase::make<VibratorCallback>(); } - auto status = hal->call(&aidl::IVibrator::composePwle, mCompositePwle, callback); + auto status = hal->composePwle(mCompositePwle, callback); if (status.isOk() && callback) { callback->waitForComplete(); diff --git a/cmds/idlcli/vibrator/CommandComposePwleV2.cpp b/cmds/idlcli/vibrator/CommandComposePwleV2.cpp index 6d3cf84a2e..bd682eacae 100644 --- a/cmds/idlcli/vibrator/CommandComposePwleV2.cpp +++ b/cmds/idlcli/vibrator/CommandComposePwleV2.cpp @@ -108,7 +108,7 @@ class CommandComposePwleV2 : public Command { } Status doMain(Args&& /*args*/) override { - auto hal = getHal<aidl::IVibrator>(); + auto hal = getHal(); if (!hal) { return UNAVAILABLE; @@ -123,7 +123,7 @@ class CommandComposePwleV2 : public Command { callback = ndk::SharedRefBase::make<VibratorCallback>(); } - auto status = hal->call(&aidl::IVibrator::composePwleV2, mCompositePwle, callback); + auto status = hal->composePwleV2(mCompositePwle, callback); if (status.isOk() && callback) { callback->waitForComplete(); diff --git a/cmds/idlcli/vibrator/CommandGetBandwidthAmplitudeMap.cpp b/cmds/idlcli/vibrator/CommandGetBandwidthAmplitudeMap.cpp index aa01a11237..44115e9a97 100644 --- a/cmds/idlcli/vibrator/CommandGetBandwidthAmplitudeMap.cpp +++ b/cmds/idlcli/vibrator/CommandGetBandwidthAmplitudeMap.cpp @@ -44,29 +44,38 @@ class CommandGetBandwidthAmplitudeMap : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; + auto hal = getHal(); + + if (!hal) { + return UNAVAILABLE; + } + std::vector<float> bandwidthAmplitude; float frequencyMinimumHz; float frequencyResolutionHz; - Status ret; - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = - hal->call(&aidl::IVibrator::getBandwidthAmplitudeMap, &bandwidthAmplitude); - statusStr = status.getDescription(); - ret = (status.isOk() ? OK : ERROR); + auto status = hal->getBandwidthAmplitudeMap(&bandwidthAmplitude); - status = hal->call(&aidl::IVibrator::getFrequencyMinimum, &frequencyMinimumHz); - ret = (status.isOk() ? OK : ERROR); + if (!status.isOk()) { + std::cout << "Status: " << status.getDescription() << std::endl; + return ERROR; + } - status = - hal->call(&aidl::IVibrator::getFrequencyResolution, &frequencyResolutionHz); - ret = (status.isOk() ? OK : ERROR); - } else { - return UNAVAILABLE; + status = hal->getFrequencyMinimum(&frequencyMinimumHz); + + if (!status.isOk()) { + std::cout << "Status: " << status.getDescription() << std::endl; + return ERROR; } - std::cout << "Status: " << statusStr << std::endl; + status = hal->getFrequencyResolution(&frequencyResolutionHz); + + if (!status.isOk()) { + std::cout << "Status: " << status.getDescription() << std::endl; + return ERROR; + } + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Bandwidth Amplitude Map: " << std::endl; float frequency = frequencyMinimumHz; for (auto &e : bandwidthAmplitude) { @@ -74,7 +83,7 @@ class CommandGetBandwidthAmplitudeMap : public Command { frequency += frequencyResolutionHz; } - return ret; + return OK; } }; diff --git a/cmds/idlcli/vibrator/CommandGetCapabilities.cpp b/cmds/idlcli/vibrator/CommandGetCapabilities.cpp index 303a9895e4..507d871cac 100644 --- a/cmds/idlcli/vibrator/CommandGetCapabilities.cpp +++ b/cmds/idlcli/vibrator/CommandGetCapabilities.cpp @@ -42,22 +42,19 @@ class CommandGetCapabilities : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - int32_t cap; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getCapabilities, &cap); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + int32_t cap; + auto status = hal->getCapabilities(&cap); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Capabilities: " << std::bitset<32>(cap) << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetCompositionDelayMax.cpp b/cmds/idlcli/vibrator/CommandGetCompositionDelayMax.cpp index 10508bd4dc..1c1eb3c6ff 100644 --- a/cmds/idlcli/vibrator/CommandGetCompositionDelayMax.cpp +++ b/cmds/idlcli/vibrator/CommandGetCompositionDelayMax.cpp @@ -44,22 +44,19 @@ class CommandGetCompositionDelayMax : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - int32_t maxDelayMs; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getCompositionDelayMax, &maxDelayMs); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + int32_t maxDelayMs; + auto status = hal->getCompositionDelayMax(&maxDelayMs); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Max Delay: " << maxDelayMs << " ms" << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetCompositionSizeMax.cpp b/cmds/idlcli/vibrator/CommandGetCompositionSizeMax.cpp index 900cb18809..cfd4c53ceb 100644 --- a/cmds/idlcli/vibrator/CommandGetCompositionSizeMax.cpp +++ b/cmds/idlcli/vibrator/CommandGetCompositionSizeMax.cpp @@ -44,22 +44,19 @@ class CommandGetCompositionSizeMax : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - int32_t maxSize; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getCompositionSizeMax, &maxSize); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + int32_t maxSize; + auto status = hal->getCompositionSizeMax(&maxSize); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Max Size: " << maxSize << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetFrequencyMinimum.cpp b/cmds/idlcli/vibrator/CommandGetFrequencyMinimum.cpp index 504c6482ad..2a614466ab 100644 --- a/cmds/idlcli/vibrator/CommandGetFrequencyMinimum.cpp +++ b/cmds/idlcli/vibrator/CommandGetFrequencyMinimum.cpp @@ -44,22 +44,19 @@ class CommandGetFrequencyMinimum : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - float frequencyMinimumHz; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getFrequencyMinimum, &frequencyMinimumHz); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + float frequencyMinimumHz; + auto status = hal->getFrequencyMinimum(&frequencyMinimumHz); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Minimum Frequency: " << frequencyMinimumHz << " Hz" << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetFrequencyResolution.cpp b/cmds/idlcli/vibrator/CommandGetFrequencyResolution.cpp index de358385a0..157d6bf732 100644 --- a/cmds/idlcli/vibrator/CommandGetFrequencyResolution.cpp +++ b/cmds/idlcli/vibrator/CommandGetFrequencyResolution.cpp @@ -44,23 +44,19 @@ class CommandGetFrequencyResolution : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - float frequencyResolutionHz; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = - hal->call(&aidl::IVibrator::getFrequencyResolution, &frequencyResolutionHz); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + float frequencyResolutionHz; + auto status = hal->getFrequencyResolution(&frequencyResolutionHz); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Frequency Resolution: " << frequencyResolutionHz << " Hz" << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetFrequencyToOutputAccelerationMap.cpp b/cmds/idlcli/vibrator/CommandGetFrequencyToOutputAccelerationMap.cpp index 2edd0caf2e..2eb45100db 100644 --- a/cmds/idlcli/vibrator/CommandGetFrequencyToOutputAccelerationMap.cpp +++ b/cmds/idlcli/vibrator/CommandGetFrequencyToOutputAccelerationMap.cpp @@ -46,26 +46,22 @@ class CommandGetFrequencyToOutputAccelerationMap : public Command { } Status doMain(Args&& /*args*/) override { - std::string statusStr; - std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap; - Status ret; - - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getFrequencyToOutputAccelerationMap, - &frequencyToOutputAccelerationMap); - statusStr = status.getDescription(); - ret = (status.isOk() ? OK : ERROR); - } else { + auto hal = getHal(); + + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap; + auto status = hal->getFrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Frequency to Output Amplitude Map: " << std::endl; for (auto& entry : frequencyToOutputAccelerationMap) { std::cout << entry.frequencyHz << " " << entry.maxOutputAccelerationGs << std::endl; } - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetPrimitiveDuration.cpp b/cmds/idlcli/vibrator/CommandGetPrimitiveDuration.cpp index 460d39e64f..c957f6b316 100644 --- a/cmds/idlcli/vibrator/CommandGetPrimitiveDuration.cpp +++ b/cmds/idlcli/vibrator/CommandGetPrimitiveDuration.cpp @@ -57,22 +57,19 @@ class CommandGetPrimitiveDuration : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - int32_t duration; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getPrimitiveDuration, mPrimitive, &duration); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + int32_t duration; + auto status = hal->getPrimitiveDuration(mPrimitive, &duration); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Duration: " << duration << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } CompositePrimitive mPrimitive; diff --git a/cmds/idlcli/vibrator/CommandGetPwleCompositionSizeMax.cpp b/cmds/idlcli/vibrator/CommandGetPwleCompositionSizeMax.cpp index b2c35519eb..c1b027833b 100644 --- a/cmds/idlcli/vibrator/CommandGetPwleCompositionSizeMax.cpp +++ b/cmds/idlcli/vibrator/CommandGetPwleCompositionSizeMax.cpp @@ -44,22 +44,19 @@ class CommandGetPwleCompositionSizeMax : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - int32_t maxSize; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getPwleCompositionSizeMax, &maxSize); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + int32_t maxSize; + auto status = hal->getPwleCompositionSizeMax(&maxSize); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Max Size: " << maxSize << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetPwlePrimitiveDurationMax.cpp b/cmds/idlcli/vibrator/CommandGetPwlePrimitiveDurationMax.cpp index 90819731c4..ed00ba0c13 100644 --- a/cmds/idlcli/vibrator/CommandGetPwlePrimitiveDurationMax.cpp +++ b/cmds/idlcli/vibrator/CommandGetPwlePrimitiveDurationMax.cpp @@ -44,22 +44,19 @@ class CommandGetPwlePrimitiveDurationMax : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - int32_t maxDurationMs; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getPwlePrimitiveDurationMax, &maxDurationMs); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + int32_t maxDurationMs; + auto status = hal->getPwlePrimitiveDurationMax(&maxDurationMs); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Primitive duration max: " << maxDurationMs << " ms" << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetPwleV2CompositionSizeMax.cpp b/cmds/idlcli/vibrator/CommandGetPwleV2CompositionSizeMax.cpp index cca072c46f..f780b8bfd7 100644 --- a/cmds/idlcli/vibrator/CommandGetPwleV2CompositionSizeMax.cpp +++ b/cmds/idlcli/vibrator/CommandGetPwleV2CompositionSizeMax.cpp @@ -44,22 +44,19 @@ class CommandGetPwleV2CompositionSizeMax : public Command { } Status doMain(Args&& /*args*/) override { - std::string statusStr; - int32_t maxSize; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getPwleV2CompositionSizeMax, &maxSize); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + int32_t maxSize; + auto status = hal->getPwleV2CompositionSizeMax(&maxSize); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Max Size: " << maxSize << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetPwleV2PrimitiveDurationMaxMillis.cpp b/cmds/idlcli/vibrator/CommandGetPwleV2PrimitiveDurationMaxMillis.cpp index dbbfe1a6d4..e84e969e7c 100644 --- a/cmds/idlcli/vibrator/CommandGetPwleV2PrimitiveDurationMaxMillis.cpp +++ b/cmds/idlcli/vibrator/CommandGetPwleV2PrimitiveDurationMaxMillis.cpp @@ -44,23 +44,19 @@ class CommandGetPwleV2PrimitiveDurationMaxMillis : public Command { } Status doMain(Args&& /*args*/) override { - std::string statusStr; - int32_t maxDurationMs; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getPwleV2PrimitiveDurationMaxMillis, - &maxDurationMs); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + int32_t maxDurationMs; + auto status = hal->getPwleV2PrimitiveDurationMaxMillis(&maxDurationMs); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Primitive duration max: " << maxDurationMs << " ms" << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetPwleV2PrimitiveDurationMinMillis.cpp b/cmds/idlcli/vibrator/CommandGetPwleV2PrimitiveDurationMinMillis.cpp index 09225c49c4..448fd2adc2 100644 --- a/cmds/idlcli/vibrator/CommandGetPwleV2PrimitiveDurationMinMillis.cpp +++ b/cmds/idlcli/vibrator/CommandGetPwleV2PrimitiveDurationMinMillis.cpp @@ -44,23 +44,19 @@ class CommandGetPwleV2PrimitiveDurationMinMillis : public Command { } Status doMain(Args&& /*args*/) override { - std::string statusStr; - int32_t minDurationMs; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getPwleV2PrimitiveDurationMinMillis, - &minDurationMs); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + int32_t minDurationMs; + auto status = hal->getPwleV2PrimitiveDurationMinMillis(&minDurationMs); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Primitive duration min: " << minDurationMs << " ms" << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetQFactor.cpp b/cmds/idlcli/vibrator/CommandGetQFactor.cpp index a2681e905b..e04bad9384 100644 --- a/cmds/idlcli/vibrator/CommandGetQFactor.cpp +++ b/cmds/idlcli/vibrator/CommandGetQFactor.cpp @@ -42,22 +42,19 @@ class CommandGetQFactor : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - float qFactor; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getQFactor, &qFactor); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + float qFactor; + auto status = hal->getQFactor(&qFactor); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Q Factor: " << qFactor << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetResonantFrequency.cpp b/cmds/idlcli/vibrator/CommandGetResonantFrequency.cpp index 81a6391de5..e222ea656e 100644 --- a/cmds/idlcli/vibrator/CommandGetResonantFrequency.cpp +++ b/cmds/idlcli/vibrator/CommandGetResonantFrequency.cpp @@ -44,22 +44,19 @@ class CommandGetResonantFrequency : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - float resonantFrequencyHz; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getResonantFrequency, &resonantFrequencyHz); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + float resonantFrequencyHz; + auto status = hal->getResonantFrequency(&resonantFrequencyHz); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Resonant Frequency: " << resonantFrequencyHz << " Hz" << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetSupportedAlwaysOnEffects.cpp b/cmds/idlcli/vibrator/CommandGetSupportedAlwaysOnEffects.cpp index edfcd9195a..9b05540fce 100644 --- a/cmds/idlcli/vibrator/CommandGetSupportedAlwaysOnEffects.cpp +++ b/cmds/idlcli/vibrator/CommandGetSupportedAlwaysOnEffects.cpp @@ -44,25 +44,22 @@ class CommandGetSupportedAlwaysOnEffects : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - std::vector<Effect> effects; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getSupportedAlwaysOnEffects, &effects); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + std::vector<Effect> effects; + auto status = hal->getSupportedAlwaysOnEffects(&effects); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Effects:" << std::endl; for (auto &e : effects) { std::cout << " " << toString(e) << std::endl; } - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetSupportedBraking.cpp b/cmds/idlcli/vibrator/CommandGetSupportedBraking.cpp index b326e07c22..f95f682fc0 100644 --- a/cmds/idlcli/vibrator/CommandGetSupportedBraking.cpp +++ b/cmds/idlcli/vibrator/CommandGetSupportedBraking.cpp @@ -44,25 +44,22 @@ class CommandGetSupportedBraking : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - std::vector<Braking> braking; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getSupportedBraking, &braking); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + std::vector<Braking> braking; + auto status = hal->getSupportedBraking(&braking); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Braking Mechanisms:" << std::endl; for (auto &e : braking) { std::cout << " " << toString(e) << std::endl; } - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetSupportedEffects.cpp b/cmds/idlcli/vibrator/CommandGetSupportedEffects.cpp index 7658f22def..05de1b87cf 100644 --- a/cmds/idlcli/vibrator/CommandGetSupportedEffects.cpp +++ b/cmds/idlcli/vibrator/CommandGetSupportedEffects.cpp @@ -44,25 +44,22 @@ class CommandGetSupportedEffects : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - std::vector<Effect> effects; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getSupportedEffects, &effects); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + std::vector<Effect> effects; + auto status = hal->getSupportedEffects(&effects); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Effects:" << std::endl; for (auto &e : effects) { std::cout << " " << toString(e) << std::endl; } - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandGetSupportedPrimitives.cpp b/cmds/idlcli/vibrator/CommandGetSupportedPrimitives.cpp index d101681914..0f33f0f2e9 100644 --- a/cmds/idlcli/vibrator/CommandGetSupportedPrimitives.cpp +++ b/cmds/idlcli/vibrator/CommandGetSupportedPrimitives.cpp @@ -44,25 +44,22 @@ class CommandGetSupportedPrimitives : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - std::vector<CompositePrimitive> primitives; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::getSupportedPrimitives, &primitives); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + std::vector<CompositePrimitive> primitives; + auto status = hal->getSupportedPrimitives(&primitives); + + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Primitives:" << std::endl; for (auto &e : primitives) { std::cout << " " << toString(e) << std::endl; } - return ret; + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandOff.cpp b/cmds/idlcli/vibrator/CommandOff.cpp index cedb9fec06..e55b44a9c8 100644 --- a/cmds/idlcli/vibrator/CommandOff.cpp +++ b/cmds/idlcli/vibrator/CommandOff.cpp @@ -42,24 +42,17 @@ class CommandOff : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - Status ret; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::off); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else if (auto hal = getHal<V1_0::IVibrator>()) { - auto status = hal->call(&V1_0::IVibrator::off); - statusStr = toString(status); - ret = status.isOk() && status == V1_0::Status::OK ? OK : ERROR; - } else { + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + auto status = hal->off(); - return ret; + std::cout << "Status: " << status.getDescription() << std::endl; + + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandOn.cpp b/cmds/idlcli/vibrator/CommandOn.cpp index 8212fc14a7..856c219750 100644 --- a/cmds/idlcli/vibrator/CommandOn.cpp +++ b/cmds/idlcli/vibrator/CommandOn.cpp @@ -67,34 +67,27 @@ class CommandOn : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - Status ret; - std::shared_ptr<VibratorCallback> callback; + auto hal = getHal(); - if (auto hal = getHal<aidl::IVibrator>()) { - ABinderProcess_setThreadPoolMaxThreadCount(1); - ABinderProcess_startThreadPool(); + if (!hal) { + return UNAVAILABLE; + } - int32_t cap; - hal->call(&aidl::IVibrator::getCapabilities, &cap); + std::shared_ptr<VibratorCallback> callback; - if (mBlocking && (cap & aidl::IVibrator::CAP_ON_CALLBACK)) { - callback = ndk::SharedRefBase::make<VibratorCallback>(); - } + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); - auto status = hal->call(&aidl::IVibrator::on, mDuration, callback); + int32_t cap; + hal->getCapabilities(&cap); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else if (auto hal = getHal<V1_0::IVibrator>()) { - auto status = hal->call(&V1_0::IVibrator::on, mDuration); - statusStr = toString(status); - ret = status.isOk() && status == V1_0::Status::OK ? OK : ERROR; - } else { - return UNAVAILABLE; + if (mBlocking && (cap & aidl::IVibrator::CAP_ON_CALLBACK)) { + callback = ndk::SharedRefBase::make<VibratorCallback>(); } - if (ret == OK && mBlocking) { + auto status = hal->on(mDuration, callback); + + if (status.isOk() && mBlocking) { if (callback) { callback->waitForComplete(); } else { @@ -102,9 +95,9 @@ class CommandOn : public Command { } } - std::cout << "Status: " << statusStr << std::endl; + std::cout << "Status: " << status.getDescription() << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } bool mBlocking; diff --git a/cmds/idlcli/vibrator/CommandPerform.cpp b/cmds/idlcli/vibrator/CommandPerform.cpp index c897686cbe..0a354e2c5a 100644 --- a/cmds/idlcli/vibrator/CommandPerform.cpp +++ b/cmds/idlcli/vibrator/CommandPerform.cpp @@ -28,34 +28,6 @@ class CommandVibrator; namespace vibrator { -/* - * The following static asserts are only relevant here because the argument - * parser uses a single implementation for determining the string names. - */ -static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) == - static_cast<uint8_t>(aidl::EffectStrength::LIGHT)); -static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) == - static_cast<uint8_t>(aidl::EffectStrength::MEDIUM)); -static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) == - static_cast<uint8_t>(aidl::EffectStrength::STRONG)); -static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) == - static_cast<uint8_t>(aidl::Effect::CLICK)); -static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) == - static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK)); -static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == static_cast<uint8_t>(aidl::Effect::TICK)); -static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == static_cast<uint8_t>(aidl::Effect::THUD)); -static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == static_cast<uint8_t>(aidl::Effect::POP)); -static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) == - static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK)); -static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) == - static_cast<uint8_t>(aidl::Effect::RINGTONE_1)); -static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) == - static_cast<uint8_t>(aidl::Effect::RINGTONE_2)); -static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) == - static_cast<uint8_t>(aidl::Effect::RINGTONE_15)); -static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) == - static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK)); - using aidl::Effect; using aidl::EffectStrength; @@ -107,61 +79,31 @@ class CommandPerform : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; + auto hal = getHal(); + + if (!hal) { + return UNAVAILABLE; + } + uint32_t lengthMs; - Status ret; std::shared_ptr<VibratorCallback> callback; - if (auto hal = getHal<aidl::IVibrator>()) { - ABinderProcess_setThreadPoolMaxThreadCount(1); - ABinderProcess_startThreadPool(); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); - int32_t cap; - hal->call(&aidl::IVibrator::getCapabilities, &cap); + int32_t cap; + hal->getCapabilities(&cap); - if (mBlocking && (cap & aidl::IVibrator::CAP_PERFORM_CALLBACK)) { - callback = ndk::SharedRefBase::make<VibratorCallback>(); - } - - int32_t aidlLengthMs; - auto status = hal->call(&aidl::IVibrator::perform, mEffect, mStrength, callback, - &aidlLengthMs); + if (mBlocking && (cap & aidl::IVibrator::CAP_PERFORM_CALLBACK)) { + callback = ndk::SharedRefBase::make<VibratorCallback>(); + } - statusStr = status.getDescription(); - lengthMs = static_cast<uint32_t>(aidlLengthMs); - ret = status.isOk() ? OK : ERROR; - } else { - Return<void> hidlRet; - V1_0::Status status; - auto callback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) { - status = retStatus; - lengthMs = retLengthMs; - }; - - if (auto hal = getHal<V1_3::IVibrator>()) { - hidlRet = - hal->call(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(mEffect), - static_cast<V1_0::EffectStrength>(mStrength), callback); - } else if (auto hal = getHal<V1_2::IVibrator>()) { - hidlRet = - hal->call(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(mEffect), - static_cast<V1_0::EffectStrength>(mStrength), callback); - } else if (auto hal = getHal<V1_1::IVibrator>()) { - hidlRet = hal->call(&V1_1::IVibrator::perform_1_1, - static_cast<V1_1::Effect_1_1>(mEffect), - static_cast<V1_0::EffectStrength>(mStrength), callback); - } else if (auto hal = getHal<V1_0::IVibrator>()) { - hidlRet = hal->call(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(mEffect), - static_cast<V1_0::EffectStrength>(mStrength), callback); - } else { - return UNAVAILABLE; - } + int32_t aidlLengthMs; + auto status = hal->perform(mEffect, mStrength, callback, &aidlLengthMs); - statusStr = toString(status); - ret = hidlRet.isOk() && status == V1_0::Status::OK ? OK : ERROR; - } + lengthMs = static_cast<uint32_t>(aidlLengthMs); - if (ret == OK && mBlocking) { + if (status.isOk() && mBlocking) { if (callback) { callback->waitForComplete(); } else { @@ -169,10 +111,10 @@ class CommandPerform : public Command { } } - std::cout << "Status: " << statusStr << std::endl; + std::cout << "Status: " << status.getDescription() << std::endl; std::cout << "Length: " << lengthMs << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } bool mBlocking; diff --git a/cmds/idlcli/vibrator/CommandSetAmplitude.cpp b/cmds/idlcli/vibrator/CommandSetAmplitude.cpp index 8b8058c4fd..8050723729 100644 --- a/cmds/idlcli/vibrator/CommandSetAmplitude.cpp +++ b/cmds/idlcli/vibrator/CommandSetAmplitude.cpp @@ -50,25 +50,17 @@ class CommandSetAmplitude : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - Status ret; - - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::setAmplitude, - static_cast<float>(mAmplitude) / UINT8_MAX); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else if (auto hal = getHal<V1_0::IVibrator>()) { - auto status = hal->call(&V1_0::IVibrator::setAmplitude, mAmplitude); - statusStr = toString(status); - ret = status.isOk() && status == V1_0::Status::OK ? OK : ERROR; - } else { + auto hal = getHal(); + + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + auto status = hal->setAmplitude(static_cast<float>(mAmplitude) / UINT8_MAX); + + std::cout << "Status: " << status.getDescription() << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } uint8_t mAmplitude; diff --git a/cmds/idlcli/vibrator/CommandSetExternalControl.cpp b/cmds/idlcli/vibrator/CommandSetExternalControl.cpp index 179579310a..8f8d4b7641 100644 --- a/cmds/idlcli/vibrator/CommandSetExternalControl.cpp +++ b/cmds/idlcli/vibrator/CommandSetExternalControl.cpp @@ -48,24 +48,17 @@ class CommandSetExternalControl : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - Status ret; - - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::setExternalControl, mEnable); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else if (auto hal = getHal<V1_3::IVibrator>()) { - auto status = hal->call(&V1_3::IVibrator::setExternalControl, mEnable); - statusStr = toString(status); - ret = status.isOk() && status == V1_0::Status::OK ? OK : ERROR; - } else { + auto hal = getHal(); + + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + auto status = hal->setExternalControl(mEnable); + + std::cout << "Status: " << status.getDescription() << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } bool mEnable; diff --git a/cmds/idlcli/vibrator/CommandSupportsAmplitudeControl.cpp b/cmds/idlcli/vibrator/CommandSupportsAmplitudeControl.cpp index cdc529a2f3..31ee954f63 100644 --- a/cmds/idlcli/vibrator/CommandSupportsAmplitudeControl.cpp +++ b/cmds/idlcli/vibrator/CommandSupportsAmplitudeControl.cpp @@ -42,15 +42,22 @@ class CommandSupportsAmplitudeControl : public Command { } Status doMain(Args && /*args*/) override { - auto ret = halCall(&V1_0::IVibrator::supportsAmplitudeControl); + auto hal = getHal(); - if (!ret.isOk()) { + if (!hal) { return UNAVAILABLE; } - std::cout << "Result: " << std::boolalpha << ret << std::endl; + int32_t cap; - return OK; + auto status = hal->getCapabilities(&cap); + + bool hasAmplitudeControl = cap & IVibrator::CAP_AMPLITUDE_CONTROL; + + std::cout << "Status: " << status.getDescription() << std::endl; + std::cout << "Result: " << std::boolalpha << hasAmplitudeControl << std::endl; + + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/idlcli/vibrator/CommandSupportsExternalControl.cpp b/cmds/idlcli/vibrator/CommandSupportsExternalControl.cpp index ed15d76286..f0c542cfe3 100644 --- a/cmds/idlcli/vibrator/CommandSupportsExternalControl.cpp +++ b/cmds/idlcli/vibrator/CommandSupportsExternalControl.cpp @@ -42,15 +42,22 @@ class CommandSupportsExternalControl : public Command { } Status doMain(Args && /*args*/) override { - auto ret = halCall(&V1_3::IVibrator::supportsExternalControl); + auto hal = getHal(); - if (!ret.isOk()) { + if (!hal) { return UNAVAILABLE; } - std::cout << "Result: " << std::boolalpha << ret << std::endl; + int32_t cap; - return OK; + auto status = hal->getCapabilities(&cap); + + bool hasExternalControl = cap & IVibrator::CAP_EXTERNAL_CONTROL; + + std::cout << "Status: " << status.getDescription() << std::endl; + std::cout << "Result: " << std::boolalpha << hasExternalControl << std::endl; + + return status.isOk() ? OK : ERROR; } }; diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 4486bd6d3e..db565513c9 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -119,7 +119,6 @@ static constexpr const char* kFuseProp = "persist.sys.fuse"; */ static constexpr const char* kAppDataIsolationEnabledProperty = "persist.zygote.app_data_isolation"; static constexpr const char* kMntSdcardfs = "/mnt/runtime/default/"; -static constexpr const char* kMntFuse = "/mnt/pass_through/0/"; static std::atomic<bool> sAppDataIsolationEnabled(false); @@ -3697,7 +3696,9 @@ binder::Status InstalldNativeService::invalidateMounts() { std::getline(in, ignored); if (android::base::GetBoolProperty(kFuseProp, false)) { - if (target.find(kMntFuse) == 0) { + const std::regex kMntFuseRe = + std::regex(R"(^/mnt/pass_through/(0|[0-9]+/[A-Z0-9]{4}-[A-Z0-9]{4}).*)"); + if (std::regex_match(target, kMntFuseRe)) { LOG(DEBUG) << "Found storage mount " << source << " at " << target; mStorageMounts[source] = target; } diff --git a/cmds/installd/TEST_MAPPING b/cmds/installd/TEST_MAPPING index fc4cfc98dc..d53c94ba55 100644 --- a/cmds/installd/TEST_MAPPING +++ b/cmds/installd/TEST_MAPPING @@ -18,10 +18,6 @@ { "name": "run_dex2oat_test" }, - // AdoptableHostTest moves packages, part of which is handled by installd - { - "name": "AdoptableHostTest" - }, { "name": "CtsUsesLibraryHostTestCases" }, diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp index c86adef118..c818e0d7ba 100644 --- a/cmds/installd/otapreopt_chroot.cpp +++ b/cmds/installd/otapreopt_chroot.cpp @@ -16,6 +16,7 @@ #include <fcntl.h> #include <linux/unistd.h> +#include <sched.h> #include <sys/mount.h> #include <sys/stat.h> #include <sys/wait.h> diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh index b7ad33144b..5690e2fe42 100644 --- a/cmds/installd/otapreopt_script.sh +++ b/cmds/installd/otapreopt_script.sh @@ -23,6 +23,9 @@ TARGET_SLOT="$1" STATUS_FD="$2" +# "1" if the script is triggered by the `UpdateEngine.triggerPostinstall` API. Empty otherwise. +TRIGGERED_BY_API="$3" + # Maximum number of packages/steps. MAXIMUM_PACKAGES=1000 @@ -53,25 +56,43 @@ fi # A source that infinitely emits arbitrary lines. # When connected to STDIN of another process, this source keeps STDIN open until # the consumer process closes STDIN or this script dies. +# In practice, the pm command keeps consuming STDIN, so we don't need to worry +# about running out of buffer space. function infinite_source { while echo .; do sleep 1 done } +if [[ "$TRIGGERED_BY_API" = "1" ]]; then + # During OTA installation, the script is called the first time, and + # `TRIGGERED_BY_API` can never be "1". `TRIGGERED_BY_API` being "1" means this + # is the second call to this script, through the + # `UpdateEngine.triggerPostinstall` API. + # When we reach here, it means Pre-reboot Dexopt is enabled in asynchronous + # mode and the job scheduler determined that it's the time to run the job. + # Start Pre-reboot Dexopt now and wait for it to finish. + infinite_source | pm art on-ota-staged --start + exit $? +fi + PR_DEXOPT_JOB_VERSION="$(pm art pr-dexopt-job --version)" if (( $? == 0 )) && (( $PR_DEXOPT_JOB_VERSION >= 3 )); then # Delegate to Pre-reboot Dexopt, a feature of ART Service. # ART Service decides what to do with this request: # - If Pre-reboot Dexopt is disabled or unsupported, the command returns - # non-zero. This is always the case if the current system is Android 14 or - # earlier. + # non-zero. + # This is always the case if the current system is Android 14 or earlier. # - If Pre-reboot Dexopt is enabled in synchronous mode, the command blocks - # until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds or - # not. This is the default behavior if the current system is Android 15. - # - If Pre-reboot Dexopt is enabled in asynchronous mode, the command schedules - # an asynchronous job and returns 0 immediately. The job will then run by the - # job scheduler when the device is idle and charging. + # until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds + # or not. + # This is the default behavior if the current system is Android 15. + # - If Pre-reboot Dexopt is enabled in asynchronous mode, the command + # schedules an asynchronous job and returns 0 immediately. + # Later, when the device is idle and charging, the job will be run by the + # job scheduler. It will call this script again through the + # `UpdateEngine.triggerPostinstall` API, with `TRIGGERED_BY_API` being "1". + # This is always the case if the current system is Android 16 or later. if infinite_source | pm art on-ota-staged --slot "$TARGET_SLOT_SUFFIX"; then # Handled by Pre-reboot Dexopt. exit 0 diff --git a/cmds/lshal/libprocpartition/include/procpartition/procpartition.h b/cmds/lshal/libprocpartition/include/procpartition/procpartition.h index ca1e690694..9c0fc18697 100644 --- a/cmds/lshal/libprocpartition/include/procpartition/procpartition.h +++ b/cmds/lshal/libprocpartition/include/procpartition/procpartition.h @@ -27,6 +27,8 @@ namespace procpartition { enum class Partition { UNKNOWN = 0, SYSTEM, + SYSTEM_EXT, + PRODUCT, VENDOR, ODM }; diff --git a/cmds/lshal/libprocpartition/procpartition.cpp b/cmds/lshal/libprocpartition/procpartition.cpp index 9645f3a3f3..35fad577a4 100644 --- a/cmds/lshal/libprocpartition/procpartition.cpp +++ b/cmds/lshal/libprocpartition/procpartition.cpp @@ -24,6 +24,8 @@ namespace procpartition { std::ostream& operator<<(std::ostream& os, Partition p) { switch (p) { case Partition::SYSTEM: return os << "system"; + case Partition::SYSTEM_EXT: return os << "system_ext"; + case Partition::PRODUCT: return os << "product"; case Partition::VENDOR: return os << "vendor"; case Partition::ODM: return os << "odm"; case Partition::UNKNOWN: // fallthrough @@ -57,6 +59,12 @@ Partition parsePartition(const std::string& s) { if (s == "system") { return Partition::SYSTEM; } + if (s == "system_ext") { + return Partition::SYSTEM_EXT; + } + if (s == "product") { + return Partition::PRODUCT; + } if (s == "vendor") { return Partition::VENDOR; } diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp index 38a125bb54..59c4d53bc0 100644 --- a/cmds/servicemanager/ServiceManager.cpp +++ b/cmds/servicemanager/ServiceManager.cpp @@ -410,7 +410,16 @@ Status ServiceManager::getService2(const std::string& name, os::Service* outServ return Status::ok(); } -Status ServiceManager::checkService(const std::string& name, os::Service* outService) { +Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) { + SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS( + PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str()))); + + *outBinder = tryGetBinder(name, false).service; + // returns ok regardless of result for legacy reasons + return Status::ok(); +} + +Status ServiceManager::checkService2(const std::string& name, os::Service* outService) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS( PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str()))); diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h index 964abee6af..5c4d891218 100644 --- a/cmds/servicemanager/ServiceManager.h +++ b/cmds/servicemanager/ServiceManager.h @@ -46,7 +46,8 @@ public: // getService will try to start any services it cannot find binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override; binder::Status getService2(const std::string& name, os::Service* outService) override; - binder::Status checkService(const std::string& name, os::Service* outService) override; + binder::Status checkService(const std::string& name, sp<IBinder>* outBinder) override; + binder::Status checkService2(const std::string& name, os::Service* outService) override; binder::Status addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) override; binder::Status listServices(int32_t dumpPriority, std::vector<std::string>* outList) override; diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp index e620770e18..7ad84faca0 100644 --- a/cmds/servicemanager/test_sm.cpp +++ b/cmds/servicemanager/test_sm.cpp @@ -204,6 +204,11 @@ TEST(GetService, HappyHappy) { sp<IBinder> outBinder; EXPECT_TRUE(sm->getService("foo", &outBinder).isOk()); EXPECT_EQ(service, outBinder); + + EXPECT_TRUE(sm->checkService2("foo", &out).isOk()); + EXPECT_EQ(service, out.get<Service::Tag::serviceWithMetadata>().service); + EXPECT_TRUE(sm->checkService("foo", &outBinder).isOk()); + EXPECT_EQ(service, outBinder); } TEST(GetService, NonExistant) { diff --git a/data/etc/Android.bp b/data/etc/Android.bp index cd8ca89de5..f320504551 100644 --- a/data/etc/Android.bp +++ b/data/etc/Android.bp @@ -119,12 +119,24 @@ prebuilt_etc { } prebuilt_etc { + name: "android.hardware.nfc.ese.prebuilt.xml", + src: "android.hardware.nfc.ese.xml", + defaults: ["frameworks_native_data_etc_defaults"], +} + +prebuilt_etc { name: "android.hardware.nfc.hce.prebuilt.xml", src: "android.hardware.nfc.hce.xml", defaults: ["frameworks_native_data_etc_defaults"], } prebuilt_etc { + name: "android.hardware.nfc.hcef.prebuilt.xml", + src: "android.hardware.nfc.hcef.xml", + defaults: ["frameworks_native_data_etc_defaults"], +} + +prebuilt_etc { name: "android.hardware.reboot_escrow.prebuilt.xml", src: "android.hardware.reboot_escrow.xml", defaults: ["frameworks_native_data_etc_defaults"], @@ -317,6 +329,12 @@ prebuilt_etc { } prebuilt_etc { + name: "android.hardware.telephony.messaging.prebuilt.xml", + src: "android.hardware.telephony.messaging.xml", + defaults: ["frameworks_native_data_etc_defaults"], +} + +prebuilt_etc { name: "android.hardware.thread_network.prebuilt.xml", src: "android.hardware.thread_network.xml", defaults: ["frameworks_native_data_etc_defaults"], @@ -505,6 +523,12 @@ prebuilt_etc { } prebuilt_etc { + name: "com.nxp.mifare.prebuilt.xml", + src: "com.nxp.mifare.xml", + defaults: ["frameworks_native_data_etc_defaults"], +} + +prebuilt_etc { name: "go_handheld_core_hardware.prebuilt.xml", src: "go_handheld_core_hardware.xml", defaults: ["frameworks_native_data_etc_defaults"], diff --git a/data/etc/android.hardware.telephony.messaging.xml b/data/etc/android.hardware.telephony.messaging.xml new file mode 100644 index 0000000000..0e96123625 --- /dev/null +++ b/data/etc/android.hardware.telephony.messaging.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2025 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- Feature for devices with messaging. --> +<permissions> + <feature name="android.hardware.telephony" /> + <feature name="android.hardware.telephony.radio.access" /> + <feature name="android.hardware.telephony.subscription" /> + <feature name="android.hardware.telephony.messaging" /> +</permissions> diff --git a/include/OWNERS b/include/OWNERS index c98e87aa74..7f847e8015 100644 --- a/include/OWNERS +++ b/include/OWNERS @@ -1,5 +1,4 @@ alecmouri@google.com -alexeykuzmin@google.com dangittik@google.com jreck@google.com lajos@google.com diff --git a/include/android/input.h b/include/android/input.h index ee98d7aee9..2f6c5b57ff 100644 --- a/include/android/input.h +++ b/include/android/input.h @@ -849,6 +849,7 @@ enum { * Refer to the documentation on the MotionEvent class for descriptions of each button. */ enum { + // LINT.IfChange(AMOTION_EVENT_BUTTON) /** primary */ AMOTION_EVENT_BUTTON_PRIMARY = 1 << 0, /** secondary */ @@ -861,6 +862,7 @@ enum { AMOTION_EVENT_BUTTON_FORWARD = 1 << 4, AMOTION_EVENT_BUTTON_STYLUS_PRIMARY = 1 << 5, AMOTION_EVENT_BUTTON_STYLUS_SECONDARY = 1 << 6, + // LINT.ThenChange(/frameworks/native/libs/input/rust/input.rs,/frameworks/native/services/inputflinger/tests/fuzzers/FuzzedInputStream.h) }; /** diff --git a/include/android/surface_control_input_receiver.h b/include/android/surface_control_input_receiver.h index f0503f6324..59d3a31b30 100644 --- a/include/android/surface_control_input_receiver.h +++ b/include/android/surface_control_input_receiver.h @@ -39,11 +39,11 @@ __BEGIN_DECLS * * \param motionEvent The motion event. This must be released with AInputEvent_release. * + * \return true if the event is handled by the client, false otherwise. * Available since API level 35. */ typedef bool (*AInputReceiver_onMotionEvent)(void *_Null_unspecified context, - AInputEvent *_Nonnull motionEvent) - __INTRODUCED_IN(__ANDROID_API_V__); + AInputEvent *_Nonnull motionEvent); /** * The AInputReceiver_onKeyEvent callback is invoked when the registered input channel receives * a key event. @@ -53,11 +53,12 @@ typedef bool (*AInputReceiver_onMotionEvent)(void *_Null_unspecified context, * * \param keyEvent The key event. This must be released with AInputEvent_release. * + * \return true if the event is handled by the client, false otherwise. System may generate + * a fallback key event if the event is not handled. * Available since API level 35. */ typedef bool (*AInputReceiver_onKeyEvent)(void *_Null_unspecified context, - AInputEvent *_Nonnull keyEvent) - __INTRODUCED_IN(__ANDROID_API_V__); + AInputEvent *_Nonnull keyEvent); typedef struct AInputReceiverCallbacks AInputReceiverCallbacks; diff --git a/include/android/system_health.h b/include/android/system_health.h index 6d59706490..4494e32815 100644 --- a/include/android/system_health.h +++ b/include/android/system_health.h @@ -316,8 +316,6 @@ int ASystemHealth_getMaxCpuHeadroomTidsSize(size_t* _Nonnull outSize); /** * Gets the range of the calculation window size for CPU headroom. * - * In API version 36, the range will be a superset of [50, 10000]. - * * Available since API level 36. * * @param outMinMillis Non-null output pointer to be set to the minimum window size in milliseconds. @@ -332,8 +330,6 @@ __INTRODUCED_IN(36); /** * Gets the range of the calculation window size for GPU headroom. * - * In API version 36, the range will be a superset of [50, 10000]. - * * Available since API level 36. * * @param outMinMillis Non-null output pointer to be set to the minimum window size in milliseconds. @@ -417,7 +413,6 @@ __INTRODUCED_IN(36); * @param outMinIntervalMillis Non-null output pointer to a int64_t, which * will be set to the minimum polling interval in milliseconds. * @return 0 on success. - * EPIPE if failed to get the minimum polling interval. * ENOTSUP if API is unsupported. */ int ASystemHealth_getCpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis) @@ -434,7 +429,6 @@ __INTRODUCED_IN(36); * @param outMinIntervalMillis Non-null output pointer to a int64_t, which * will be set to the minimum polling interval in milliseconds. * @return 0 on success. - * EPIPE if failed to get the minimum polling interval. * ENOTSUP if API is unsupported. */ int ASystemHealth_getGpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis) diff --git a/include/audiomanager/IAudioManager.h b/include/audiomanager/IAudioManager.h index a35a145084..b0641b826e 100644 --- a/include/audiomanager/IAudioManager.h +++ b/include/audiomanager/IAudioManager.h @@ -17,6 +17,7 @@ #ifndef ANDROID_IAUDIOMANAGER_H #define ANDROID_IAUDIOMANAGER_H +#include <android/media/IAudioManagerNative.h> #include <audiomanager/AudioManager.h> #include <utils/Errors.h> #include <binder/IInterface.h> @@ -34,20 +35,23 @@ public: // These transaction IDs must be kept in sync with the method order from // IAudioService.aidl. enum { - TRACK_PLAYER = IBinder::FIRST_CALL_TRANSACTION, - PLAYER_ATTRIBUTES = IBinder::FIRST_CALL_TRANSACTION + 1, - PLAYER_EVENT = IBinder::FIRST_CALL_TRANSACTION + 2, - RELEASE_PLAYER = IBinder::FIRST_CALL_TRANSACTION + 3, - TRACK_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 4, - RECORDER_EVENT = IBinder::FIRST_CALL_TRANSACTION + 5, - RELEASE_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 6, - PLAYER_SESSION_ID = IBinder::FIRST_CALL_TRANSACTION + 7, - PORT_EVENT = IBinder::FIRST_CALL_TRANSACTION + 8, - PERMISSION_UPDATE_BARRIER = IBinder::FIRST_CALL_TRANSACTION + 9, + GET_NATIVE_INTERFACE = IBinder::FIRST_CALL_TRANSACTION, + TRACK_PLAYER = IBinder::FIRST_CALL_TRANSACTION + 1, + PLAYER_ATTRIBUTES = IBinder::FIRST_CALL_TRANSACTION + 2, + PLAYER_EVENT = IBinder::FIRST_CALL_TRANSACTION + 3, + RELEASE_PLAYER = IBinder::FIRST_CALL_TRANSACTION + 4, + TRACK_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 5, + RECORDER_EVENT = IBinder::FIRST_CALL_TRANSACTION + 6, + RELEASE_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 7, + PLAYER_SESSION_ID = IBinder::FIRST_CALL_TRANSACTION + 8, + PORT_EVENT = IBinder::FIRST_CALL_TRANSACTION + 9, + PERMISSION_UPDATE_BARRIER = IBinder::FIRST_CALL_TRANSACTION + 10, }; DECLARE_META_INTERFACE(AudioManager) + virtual sp<media::IAudioManagerNative> getNativeInterface() = 0; + // The parcels created by these methods must be kept in sync with the // corresponding methods from IAudioService.aidl and objects it imports. virtual audio_unique_id_t trackPlayer(player_type_t playerType, audio_usage_t usage, diff --git a/include/audiomanager/OWNERS b/include/audiomanager/OWNERS index 2bd527cc3f..58257baf20 100644 --- a/include/audiomanager/OWNERS +++ b/include/audiomanager/OWNERS @@ -1,2 +1,3 @@ +atneya@google.com elaurent@google.com jmtrivi@google.com diff --git a/include/ftl/finalizer.h b/include/ftl/finalizer.h new file mode 100644 index 0000000000..0251957ad0 --- /dev/null +++ b/include/ftl/finalizer.h @@ -0,0 +1,211 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <cstddef> + +#include <functional> +#include <type_traits> +#include <utility> + +#include <ftl/function.h> + +namespace android::ftl { + +// An RAII wrapper that invokes a function object as a finalizer when destroyed. +// +// The function object must take no arguments, and must return void. If the function object needs +// any context for the call, it must store it itself, for example with a lambda capture. +// +// The stored function object will be called once (unless canceled via the `cancel()` member +// function) at the first of: +// +// - The Finalizer instance is destroyed. +// - `operator()` is used to invoke the contained function. +// - The Finalizer instance is move-assigned a new value. The function being replaced will be +// invoked, and the replacement will be stored to be called later. +// +// The intent with this class is to keep cleanup code next to the code that requires that +// cleanup be performed. +// +// bool read_file(std::string filename) { +// FILE* f = fopen(filename.c_str(), "rb"); +// if (f == nullptr) return false; +// const auto cleanup = ftl::Finalizer([f]() { fclose(f); }); +// // fread(...), etc +// return true; +// } +// +// The `FinalFunction` template argument to Finalizer<FinalFunction> allows a polymorphic function +// type for storing the finalization function, such as `std::function` or `ftl::Function`. +// +// For convenience, this header defines a few useful aliases for using those types. +// +// - `FinalizerStd`, an alias for `Finalizer<std::function<void()>>` +// - `FinalizerFtl`, an alias for `Finalizer<ftl::Function<void()>>` +// - `FinalizerFtl1`, an alias for `Finalizer<ftl::Function<void(), 1>>` +// - `FinalizerFtl2`, an alias for `Finalizer<ftl::Function<void(), 2>>` +// - `FinalizerFtl3`, an alias for `Finalizer<ftl::Function<void(), 3>>` +// +// Clients of this header are free to define other aliases they need. +// +// A Finalizer that uses a polymorphic function type can be returned from a function call and/or +// stored as member data (to be destroyed along with the containing class). +// +// auto register(Observer* observer) -> ftl::FinalizerStd<void()> { +// const auto id = observers.add(observer); +// return ftl::Finalizer([id]() { observers.remove(id); }); +// } +// +// { +// const auto _ = register(observer); +// // do the things that required the registered observer. +// } +// // the observer is removed. +// +// Cautions: +// +// 1. When a Finalizer is stored as member data, you will almost certainly want that cleanup to +// happen first, before the rest of the other member data is destroyed. For safety you should +// assume that the finalization function will access that data directly or indirectly. +// +// This means that Finalizers should be defined last, after all other normal member data in a +// class. +// +// class MyClass { +// public: +// bool initialize() { +// ready_ = true; +// cleanup_ = ftl::Finalizer([this]() { ready_ = false; }); +// return true; +// } +// +// bool ready_ = false; +// +// // Finalizers should be last so other class members can be accessed before being +// // destroyed. +// ftl::FinalizerStd<void()> cleanup_; +// }; +// +// 2. Care must be taken to use `ftl::Finalizer()` when constructing locally from a lambda. If you +// forget to do so, you are just creating a lambda that won't be automatically invoked! +// +// const auto bad = [&counter](){ ++counter; }; // Just a lambda instance +// const auto good = ftl::Finalizer([&counter](){ ++counter; }); +// +template <typename FinalFunction> +class Finalizer final { + // requires(std::is_invocable_r_v<void, FinalFunction>) + static_assert(std::is_invocable_r_v<void, FinalFunction>); + + public: + // A default constructed Finalizer does nothing when destroyed. + // requires(std::is_default_constructible_v<FinalFunction>) + constexpr Finalizer() = default; + + // Constructs a Finalizer from a function object. + // requires(std::is_invocable_v<F>) + template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>> + [[nodiscard]] explicit constexpr Finalizer(F&& function) + : Finalizer(std::forward<F>(function), false) {} + + constexpr ~Finalizer() { maybe_invoke(); } + + // Disallow copying. + Finalizer(const Finalizer& that) = delete; + auto operator=(const Finalizer& that) = delete; + + // Move construction + // requires(std::is_move_constructible_v<FinalFunction>) + [[nodiscard]] constexpr Finalizer(Finalizer&& that) + : Finalizer(std::move(that.function_), std::exchange(that.canceled_, true)) {} + + // Implicit conversion move construction + // requires(!std::is_same_v<Finalizer, Finalizer<F>>) + template <typename F, typename = std::enable_if_t<!std::is_same_v<Finalizer, Finalizer<F>>>> + // NOLINTNEXTLINE(google-explicit-constructor, cppcoreguidelines-rvalue-reference-param-not-moved) + [[nodiscard]] constexpr Finalizer(Finalizer<F>&& that) + : Finalizer(std::move(that.function_), std::exchange(that.canceled_, true)) {} + + // Move assignment + // requires(std::is_move_assignable_v<FinalFunction>) + constexpr auto operator=(Finalizer&& that) -> Finalizer& { + maybe_invoke(); + + function_ = std::move(that.function_); + canceled_ = std::exchange(that.canceled_, true); + + return *this; + } + + // Implicit conversion move assignment + // requires(!std::is_same_v<Finalizer, Finalizer<F>>) + template <typename F, typename = std::enable_if_t<!std::is_same_v<Finalizer, Finalizer<F>>>> + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + constexpr auto operator=(Finalizer<F>&& that) -> Finalizer& { + *this = Finalizer(std::move(that.function_), std::exchange(that.canceled_, true)); + return *this; + } + + // Cancels the final function, preventing it from being invoked. + constexpr void cancel() { + canceled_ = true; + maybe_nullify_function(); + } + + // Invokes the final function now, if not already invoked. + constexpr void operator()() { maybe_invoke(); } + + private: + template <typename> + friend class Finalizer; + + template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>> + [[nodiscard]] explicit constexpr Finalizer(F&& function, bool canceled) + : function_(std::forward<F>(function)), canceled_(canceled) {} + + constexpr void maybe_invoke() { + if (!std::exchange(canceled_, true)) { + std::invoke(function_); + maybe_nullify_function(); + } + } + + constexpr void maybe_nullify_function() { + // Sets function_ to nullptr if that is supported for the backing type. + if constexpr (std::is_assignable_v<FinalFunction, nullptr_t>) { + function_ = nullptr; + } + } + + FinalFunction function_; + bool canceled_ = true; +}; + +template <typename F> +Finalizer(F&&) -> Finalizer<std::decay_t<F>>; + +// A standard alias for using `std::function` as the polymorphic function type. +using FinalizerStd = Finalizer<std::function<void()>>; + +// Helpful aliases for using `ftl::Function` as the polymorphic function type. +using FinalizerFtl = Finalizer<Function<void()>>; +using FinalizerFtl1 = Finalizer<Function<void(), 1>>; +using FinalizerFtl2 = Finalizer<Function<void(), 2>>; +using FinalizerFtl3 = Finalizer<Function<void(), 3>>; + +} // namespace android::ftl
\ No newline at end of file diff --git a/include/ftl/ignore.h b/include/ftl/ignore.h new file mode 100644 index 0000000000..1468fa2498 --- /dev/null +++ b/include/ftl/ignore.h @@ -0,0 +1,42 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +namespace android::ftl { + +// An alternative to `std::ignore` that makes it easy to ignore multiple values. +// +// Examples: +// +// void ftl_ignore_multiple(int arg1, const char* arg2, std::string arg3) { +// // When invoked, all the arguments are ignored. +// ftl::ignore(arg1, arg2, arg3); +// } +// +// void ftl_ignore_single(int arg) { +// // It can be used like std::ignore to ignore a single value +// ftl::ignore = arg; +// } +// +inline constexpr struct { + // NOLINTNEXTLINE(misc-unconventional-assign-operator, readability-named-parameter) + constexpr auto operator=(auto&&) const -> decltype(*this) { return *this; } + // NOLINTNEXTLINE(readability-named-parameter) + constexpr void operator()(auto&&...) const {} +} ignore; + +} // namespace android::ftl
\ No newline at end of file diff --git a/include/ftl/small_map.h b/include/ftl/small_map.h index 83d5967464..96d35cd21e 100644 --- a/include/ftl/small_map.h +++ b/include/ftl/small_map.h @@ -234,6 +234,12 @@ class SmallMap final { // bool erase(const key_type& key) { return erase(key, begin()); } + // Removes a mapping. + // + // The last() and end() iterators, as well as those to the erased mapping, are invalidated. + // + void erase(iterator it) { map_.unstable_erase(it); } + // Removes all mappings. // // All iterators are invalidated. diff --git a/include/input/BlockingQueue.h b/include/input/BlockingQueue.h index f848c82c42..6e32de6d86 100644 --- a/include/input/BlockingQueue.h +++ b/include/input/BlockingQueue.h @@ -16,6 +16,7 @@ #pragma once +#include <input/PrintTools.h> #include <condition_variable> #include <functional> #include <list> @@ -126,11 +127,21 @@ public: * Primary used for debugging. * Does not block. */ - size_t size() { + size_t size() const { std::scoped_lock lock(mLock); return mQueue.size(); } + bool empty() const { + std::scoped_lock lock(mLock); + return mQueue.empty(); + } + + std::string dump(std::string (*toString)(const T&) = constToString) const { + std::scoped_lock lock(mLock); + return dumpContainer(mQueue, toString); + } + private: const std::optional<size_t> mCapacity; /** @@ -140,7 +151,7 @@ private: /** * Lock for accessing and waiting on elements. */ - std::mutex mLock; + mutable std::mutex mLock; std::list<T> mQueue GUARDED_BY(mLock); }; diff --git a/include/input/DisplayTopologyGraph.h b/include/input/DisplayTopologyGraph.h index 90427bd76d..9fc080d6f8 100644 --- a/include/input/DisplayTopologyGraph.h +++ b/include/input/DisplayTopologyGraph.h @@ -42,8 +42,12 @@ enum class DisplayTopologyPosition : int32_t { */ struct DisplayTopologyAdjacentDisplay { ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID; + // Position of the adjacent display, relative to the source display. DisplayTopologyPosition position; - float offsetPx; + // The offset in DP of the adjacent display, relative to the source display. + float offsetDp; + + std::string dump() const; }; /** @@ -52,6 +56,10 @@ struct DisplayTopologyAdjacentDisplay { struct DisplayTopologyGraph { ui::LogicalDisplayId primaryDisplayId = ui::LogicalDisplayId::INVALID; std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>> graph; + std::unordered_map<ui::LogicalDisplayId, int> displaysDensity; + + bool isValid() const; + std::string dump() const; }; } // namespace android diff --git a/include/input/Input.h b/include/input/Input.h index 2cabd56204..002b3a7d15 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -92,11 +92,23 @@ enum { static_cast<int32_t>(android::os::MotionEventFlag::NO_FOCUS_CHANGE), /** - * This event was generated or modified by accessibility service. + * This event was injected from some AccessibilityService, which may be either an + * Accessibility Tool OR a service using that API for purposes other than assisting users + * with disabilities. */ AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT = static_cast<int32_t>(android::os::MotionEventFlag::IS_ACCESSIBILITY_EVENT), + /** + * This event was injected from an AccessibilityService with the + * AccessibilityServiceInfo#isAccessibilityTool property set to true. These services (known as + * "Accessibility Tools") are used to assist users with disabilities, so events from these + * services should be able to reach all Views including Views which set + * View#isAccessibilityDataSensitive to true. + */ + AMOTION_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL = + static_cast<int32_t>(android::os::MotionEventFlag::INJECTED_FROM_ACCESSIBILITY_TOOL), + AMOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS = static_cast<int32_t>(android::os::MotionEventFlag::TARGET_ACCESSIBILITY_FOCUS), @@ -304,6 +316,19 @@ struct PointerProperties; bool isStylusEvent(uint32_t source, const std::vector<PointerProperties>& properties); +bool isStylusHoverEvent(uint32_t source, const std::vector<PointerProperties>& properties, + int32_t action); + +bool isFromMouse(uint32_t source, ToolType tooltype); + +bool isFromTouchpad(uint32_t source, ToolType tooltype); + +bool isFromDrawingTablet(uint32_t source, ToolType tooltype); + +bool isHoverAction(int32_t action); + +bool isMouseOrTouchpad(uint32_t sources); + /* * Flags that flow alongside events in the input dispatch system to help with certain * policy decisions such as waking from device sleep. @@ -347,6 +372,9 @@ enum { POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY = android::os::IInputConstants::POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY, + POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL = + android::os::IInputConstants::POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL, + /* These flags are set by the input dispatcher. */ // Indicates that the input event was injected. diff --git a/include/input/InputFlags.h b/include/input/InputFlags.h new file mode 100644 index 0000000000..16e754e210 --- /dev/null +++ b/include/input/InputFlags.h @@ -0,0 +1,49 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +namespace android { + +class InputFlags { +public: + /** + * Check if connected displays feature is enabled, either via the feature flag or settings + * override. Developer setting override allows enabling all the "desktop experiences" features + * including input related connected_displays_cursor flag. + * + * The developer settings override is prioritised over aconfig flags. Any tests that require + * applicable aconfig flags to be disabled with SCOPED_FLAG_OVERRIDE also need this developer + * option to be reset locally. + * + * Also note the developer setting override is only applicable to the desktop experiences + * related features. + * + * To enable only the input flag run: + * adb shell aflags enable com.android.input.flags.connected_displays_cursor + * To override this flag and enable all "desktop experiences" features run: + * adb shell aflags enable com.android.window.flags.enable_desktop_mode_through_dev_option + * adb shell setprop persist.wm.debug.desktop_experience_devopts 1 + */ + static bool connectedDisplaysCursorEnabled(); + + /** + * Check if both connectedDisplaysCursor and associatedDisplayCursorBugfix is enabled. + */ + static bool connectedDisplaysCursorAndAssociatedDisplayCursorBugfixEnabled(); +}; + +} // namespace android diff --git a/include/input/InputVerifier.h b/include/input/InputVerifier.h index 14dd463425..7d3fb469c6 100644 --- a/include/input/InputVerifier.h +++ b/include/input/InputVerifier.h @@ -47,9 +47,10 @@ public: InputVerifier(const std::string& name); android::base::Result<void> processMovement(int32_t deviceId, int32_t source, int32_t action, - uint32_t pointerCount, + int32_t actionButton, uint32_t pointerCount, const PointerProperties* pointerProperties, - const PointerCoords* pointerCoords, int32_t flags); + const PointerCoords* pointerCoords, int32_t flags, + int32_t buttonState); void resetDevice(int32_t deviceId); diff --git a/include/input/PrintTools.h b/include/input/PrintTools.h index 3470be4dce..71c215f723 100644 --- a/include/input/PrintTools.h +++ b/include/input/PrintTools.h @@ -19,13 +19,18 @@ #include <bitset> #include <map> #include <optional> -#include <set> +#include <ranges> #include <sstream> #include <string> #include <vector> namespace android { +namespace internal { +template <typename T> +concept Container = std::ranges::range<T>; +} + template <size_t N> std::string bitsetToString(const std::bitset<N>& bitset) { if (bitset.none()) { @@ -72,10 +77,12 @@ inline std::string toString(const std::optional<T>& optional, /** * Convert a set of integral types to string. */ -template <typename T> -std::string dumpSet(const std::set<T>& v, std::string (*toString)(const T&) = constToString) { +template <internal::Container T> +std::string dumpContainer( + const T& container, + std::string (*toString)(const std::ranges::range_value_t<T>&) = constToString) { std::string out; - for (const T& entry : v) { + for (const auto& entry : container) { out += out.empty() ? "{" : ", "; out += toString(entry); } diff --git a/include/private/OWNERS b/include/private/OWNERS index 37da96d488..db3ae48698 100644 --- a/include/private/OWNERS +++ b/include/private/OWNERS @@ -1,3 +1,4 @@ # ADPF per-file thermal_private.h = file:platform/frameworks/base:/ADPF_OWNERS per-file performance_hint_private.h = file:platform/frameworks/base:/ADPF_OWNERS +per-file system_health_private.h = file:platform/frameworks/base:/ADPF_OWNERS diff --git a/services/surfaceflinger/RenderArea.cpp b/include/private/system_health_private.h index 5fea521f18..05a5a06c9c 100644 --- a/services/surfaceflinger/RenderArea.cpp +++ b/include/private/system_health_private.h @@ -1,5 +1,5 @@ /* - * Copyright 2017 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,18 +14,19 @@ * limitations under the License. */ -#include "RenderArea.h" +#ifndef ANDROID_PRIVATE_NATIVE_SYSTEM_HEALTH_H +#define ANDROID_PRIVATE_NATIVE_SYSTEM_HEALTH_H -namespace android { +#include <stdint.h> -float RenderArea::getCaptureFillValue(CaptureFill captureFill) { - switch(captureFill) { - case CaptureFill::CLEAR: - return 0.0f; - case CaptureFill::OPAQUE: - default: - return 1.0f; - } -} +__BEGIN_DECLS + +/** + * For testing only. + */ +void ASystemHealth_setIHintManagerForTesting(void* iManager); + +__END_DECLS + +#endif // ANDROID_PRIVATE_NATIVE_SYSTEM_HEALTH_H -} // namespace android diff --git a/libs/attestation/OWNERS b/libs/attestation/OWNERS index 4dbb0eae5c..76811f2551 100644 --- a/libs/attestation/OWNERS +++ b/libs/attestation/OWNERS @@ -1,2 +1 @@ -chaviw@google.com -svv@google.com
\ No newline at end of file +svv@google.com diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index aac369ddd1..a3499c1963 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -269,6 +269,7 @@ cc_defaults { "-Wzero-as-null-pointer-constant", "-Wreorder-init-list", "-Wunused-const-variable", + "-Wunused-result", "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION", "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION", // Hide symbols by default and set the BUILDING_LIBBINDER macro so that @@ -276,15 +277,6 @@ cc_defaults { "-fvisibility=hidden", "-DBUILDING_LIBBINDER", ], - - target: { - vendor: { - // Trimming the exported symbols reveals a bug in vendor code, so - // disable it for the vendor variant for now. http://b/349657329 - // TODO: Fix the issue and remove this override. - cflags: ["-fvisibility=default"], - }, - }, } cc_defaults { @@ -826,6 +818,7 @@ cc_library { // so we restrict its visibility to the Trusty-specific packages. visibility: [ ":__subpackages__", + "//hardware/interfaces/security/see:__subpackages__", "//system/core/trusty:__subpackages__", "//vendor:__subpackages__", ], diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp index ee3d6af742..b1c8994b05 100644 --- a/libs/binder/BackendUnifiedServiceManager.cpp +++ b/libs/binder/BackendUnifiedServiceManager.cpp @@ -130,7 +130,13 @@ os::ServiceWithMetadata createServiceWithMetadata(const sp<IBinder>& service, bo bool BinderCacheWithInvalidation::isClientSideCachingEnabled(const std::string& serviceName) { sp<ProcessState> self = ProcessState::selfOrNull(); - if (!self || self->getThreadPoolMaxTotalThreadCount() <= 0) { + // Should not cache if process state could not be found, or if thread pool + // max could is not greater than zero. + if (!self) { + ALOGW("Service retrieved before binder threads started. If they are to be started, " + "consider starting binder threads earlier."); + return false; + } else if (self->getThreadPoolMaxTotalThreadCount() <= 0) { ALOGW("Thread Pool max thread count is 0. Cannot cache binder as linkToDeath cannot be " "implemented. serviceName: %s", serviceName.c_str()); @@ -215,7 +221,9 @@ Status BackendUnifiedServiceManager::getService(const ::std::string& name, sp<IBinder>* _aidl_return) { os::Service service; Status status = getService2(name, &service); - *_aidl_return = service.get<os::Service::Tag::serviceWithMetadata>().service; + if (status.isOk()) { + *_aidl_return = service.get<os::Service::Tag::serviceWithMetadata>().service; + } return status; } @@ -238,7 +246,17 @@ Status BackendUnifiedServiceManager::getService2(const ::std::string& name, os:: return status; } -Status BackendUnifiedServiceManager::checkService(const ::std::string& name, os::Service* _out) { +Status BackendUnifiedServiceManager::checkService(const ::std::string& name, + sp<IBinder>* _aidl_return) { + os::Service service; + Status status = checkService2(name, &service); + if (status.isOk()) { + *_aidl_return = service.get<os::Service::Tag::serviceWithMetadata>().service; + } + return status; +} + +Status BackendUnifiedServiceManager::checkService2(const ::std::string& name, os::Service* _out) { os::Service service; if (returnIfCached(name, _out)) { return Status::ok(); @@ -246,7 +264,7 @@ Status BackendUnifiedServiceManager::checkService(const ::std::string& name, os: Status status = Status::ok(); if (mTheRealServiceManager) { - status = mTheRealServiceManager->checkService(name, &service); + status = mTheRealServiceManager->checkService2(name, &service); } if (status.isOk()) { status = toBinderService(name, service, _out); diff --git a/libs/binder/BackendUnifiedServiceManager.h b/libs/binder/BackendUnifiedServiceManager.h index 2496f62503..c14f28063f 100644 --- a/libs/binder/BackendUnifiedServiceManager.h +++ b/libs/binder/BackendUnifiedServiceManager.h @@ -122,7 +122,8 @@ public: binder::Status getService(const ::std::string& name, sp<IBinder>* _aidl_return) override; binder::Status getService2(const ::std::string& name, os::Service* out) override; - binder::Status checkService(const ::std::string& name, os::Service* out) override; + binder::Status checkService(const ::std::string& name, sp<IBinder>* _aidl_return) override; + binder::Status checkService2(const ::std::string& name, os::Service* out) override; binder::Status addService(const ::std::string& name, const sp<IBinder>& service, bool allowIsolated, int32_t dumpPriority) override; binder::Status listServices(int32_t dumpPriority, diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp index 53bd08d420..bc7ae37ff0 100644 --- a/libs/binder/Binder.cpp +++ b/libs/binder/Binder.cpp @@ -38,6 +38,7 @@ #endif #include "BuildFlags.h" +#include "Constants.h" #include "OS.h" #include "RpcState.h" @@ -70,8 +71,6 @@ constexpr bool kEnableRecording = true; constexpr bool kEnableRecording = false; #endif -// Log any reply transactions for which the data exceeds this size -#define LOG_REPLIES_OVER_SIZE (300 * 1024) // --------------------------------------------------------------------------- IBinder::IBinder() @@ -288,7 +287,7 @@ public: // for below objects RpcMutex mLock; std::set<sp<RpcServerLink>> mRpcServerLinks; - BpBinder::ObjectManager mObjects; + BpBinder::ObjectManager mObjectMgr; unique_fd mRecordingFd; }; @@ -412,7 +411,7 @@ status_t BBinder::transact( // In case this is being transacted on in the same process. if (reply != nullptr) { reply->setDataPosition(0); - if (reply->dataSize() > LOG_REPLIES_OVER_SIZE) { + if (reply->dataSize() > binder::kLogTransactionsOverBytes) { ALOGW("Large reply transaction of %zu bytes, interface descriptor %s, code %d", reply->dataSize(), String8(getInterfaceDescriptor()).c_str(), code); } @@ -468,7 +467,7 @@ void* BBinder::attachObject(const void* objectID, void* object, void* cleanupCoo LOG_ALWAYS_FATAL_IF(!e, "no memory"); RpcMutexUniqueLock _l(e->mLock); - return e->mObjects.attach(objectID, object, cleanupCookie, func); + return e->mObjectMgr.attach(objectID, object, cleanupCookie, func); } void* BBinder::findObject(const void* objectID) const @@ -477,7 +476,7 @@ void* BBinder::findObject(const void* objectID) const if (!e) return nullptr; RpcMutexUniqueLock _l(e->mLock); - return e->mObjects.find(objectID); + return e->mObjectMgr.find(objectID); } void* BBinder::detachObject(const void* objectID) { @@ -485,7 +484,7 @@ void* BBinder::detachObject(const void* objectID) { if (!e) return nullptr; RpcMutexUniqueLock _l(e->mLock); - return e->mObjects.detach(objectID); + return e->mObjectMgr.detach(objectID); } void BBinder::withLock(const std::function<void()>& doWithLock) { @@ -501,7 +500,7 @@ sp<IBinder> BBinder::lookupOrCreateWeak(const void* objectID, object_make_func m Extras* e = getOrCreateExtras(); LOG_ALWAYS_FATAL_IF(!e, "no memory"); RpcMutexUniqueLock _l(e->mLock); - return e->mObjects.lookupOrCreateWeak(objectID, make, makeArgs); + return e->mObjectMgr.lookupOrCreateWeak(objectID, make, makeArgs); } BBinder* BBinder::localBinder() diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp index 3758b6521c..c13e0f9e9c 100644 --- a/libs/binder/BpBinder.cpp +++ b/libs/binder/BpBinder.cpp @@ -28,6 +28,7 @@ #include <stdio.h> #include "BuildFlags.h" +#include "Constants.h" #include "file.h" //#undef ALOGV @@ -63,9 +64,6 @@ std::atomic<uint32_t> BpBinder::sBinderProxyCountWarned(0); static constexpr uint32_t kBinderProxyCountWarnInterval = 5000; -// Log any transactions for which the data exceeds this size -#define LOG_TRANSACTIONS_OVER_SIZE (300 * 1024) - enum { LIMIT_REACHED_MASK = 0x80000000, // A flag denoting that the limit has been reached WARNING_REACHED_MASK = 0x40000000, // A flag denoting that the warning has been reached @@ -78,7 +76,16 @@ BpBinder::ObjectManager::ObjectManager() BpBinder::ObjectManager::~ObjectManager() { - kill(); + const size_t N = mObjects.size(); + ALOGV("Killing %zu objects in manager %p", N, this); + for (auto i : mObjects) { + const entry_t& e = i.second; + if (e.func != nullptr) { + e.func(i.first, e.object, e.cleanupCookie); + } + } + + mObjects.clear(); } void* BpBinder::ObjectManager::attach(const void* objectID, void* object, void* cleanupCookie, @@ -144,20 +151,6 @@ sp<IBinder> BpBinder::ObjectManager::lookupOrCreateWeak(const void* objectID, ob return newObj; } -void BpBinder::ObjectManager::kill() -{ - const size_t N = mObjects.size(); - ALOGV("Killing %zu objects in manager %p", N, this); - for (auto i : mObjects) { - const entry_t& e = i.second; - if (e.func != nullptr) { - e.func(i.first, e.object, e.cleanupCookie); - } - } - - mObjects.clear(); -} - // --------------------------------------------------------------------------- sp<BpBinder> BpBinder::create(int32_t handle, std::function<void()>* postTask) { @@ -408,9 +401,11 @@ status_t BpBinder::transact( status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags); } - if (data.dataSize() > LOG_TRANSACTIONS_OVER_SIZE) { + + if (data.dataSize() > binder::kLogTransactionsOverBytes) { RpcMutexUniqueLock _l(mLock); - ALOGW("Large outgoing transaction of %zu bytes, interface descriptor %s, code %d", + ALOGW("Large outgoing transaction of %zu bytes, interface descriptor %s, code %d was " + "sent", data.dataSize(), String8(mDescriptorCache).c_str(), code); } @@ -697,19 +692,19 @@ void BpBinder::reportOneDeath(const Obituary& obit) void* BpBinder::attachObject(const void* objectID, void* object, void* cleanupCookie, object_cleanup_func func) { RpcMutexUniqueLock _l(mLock); - ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects); - return mObjects.attach(objectID, object, cleanupCookie, func); + ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjectMgr); + return mObjectMgr.attach(objectID, object, cleanupCookie, func); } void* BpBinder::findObject(const void* objectID) const { RpcMutexUniqueLock _l(mLock); - return mObjects.find(objectID); + return mObjectMgr.find(objectID); } void* BpBinder::detachObject(const void* objectID) { RpcMutexUniqueLock _l(mLock); - return mObjects.detach(objectID); + return mObjectMgr.detach(objectID); } void BpBinder::withLock(const std::function<void()>& doWithLock) { @@ -720,7 +715,7 @@ void BpBinder::withLock(const std::function<void()>& doWithLock) { sp<IBinder> BpBinder::lookupOrCreateWeak(const void* objectID, object_make_func make, const void* makeArgs) { RpcMutexUniqueLock _l(mLock); - return mObjects.lookupOrCreateWeak(objectID, make, makeArgs); + return mObjectMgr.lookupOrCreateWeak(objectID, make, makeArgs); } BpBinder* BpBinder::remoteBinder() diff --git a/libs/binder/Constants.h b/libs/binder/Constants.h new file mode 100644 index 0000000000..b75493cb8a --- /dev/null +++ b/libs/binder/Constants.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +namespace android::binder { + +/** + * See also BINDER_VM_SIZE. In kernel binder, the sum of all transactions must be allocated in this + * space. Large transactions are very error prone. In general, we should work to reduce this limit. + * The same limit is used in RPC binder for consistency. + */ +constexpr size_t kLogTransactionsOverBytes = 300 * 1024; + +/** + * See b/392575419 - this limit is chosen for a specific usecase, because RPC binder does not have + * support for shared memory in the Android Baklava timeframe. This was 100 KB during and before + * Android V. + * + * Keeping this low helps preserve overall system performance. Transactions of this size are far too + * expensive to make multiple copies over binder or sockets, and they should be avoided if at all + * possible and transition to shared memory. + */ +constexpr size_t kRpcTransactionLimitBytes = 600 * 1024; + +} // namespace android::binder diff --git a/libs/binder/IActivityManager.cpp b/libs/binder/IActivityManager.cpp index 152c815ec3..83f4719de2 100644 --- a/libs/binder/IActivityManager.cpp +++ b/libs/binder/IActivityManager.cpp @@ -147,9 +147,11 @@ public: data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor()); data.writeInt32(uid); data.writeString16(callingPackage); - remote()->transact(IS_UID_ACTIVE_TRANSACTION, data, &reply); + status_t err = remote()->transact(IS_UID_ACTIVE_TRANSACTION, data, &reply); // fail on exception - if (reply.readExceptionCode() != 0) return false; + if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) { + return false; + } return reply.readInt32() == 1; } @@ -159,9 +161,9 @@ public: data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor()); data.writeInt32(uid); data.writeString16(callingPackage); - remote()->transact(GET_UID_PROCESS_STATE_TRANSACTION, data, &reply); + status_t err = remote()->transact(GET_UID_PROCESS_STATE_TRANSACTION, data, &reply); // fail on exception - if (reply.readExceptionCode() != 0) { + if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) { return ActivityManager::PROCESS_STATE_UNKNOWN; } return reply.readInt32(); @@ -192,7 +194,7 @@ public: data.writeInt32(appPid); status_t err = remote()->transact(LOG_FGS_API_BEGIN_TRANSACTION, data, &reply, IBinder::FLAG_ONEWAY); - if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) { + if (err != NO_ERROR) { ALOGD("%s: FGS Logger Transaction failed, %d", __func__, err); return err; } @@ -207,7 +209,7 @@ public: data.writeInt32(appPid); status_t err = remote()->transact(LOG_FGS_API_END_TRANSACTION, data, &reply, IBinder::FLAG_ONEWAY); - if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) { + if (err != NO_ERROR) { ALOGD("%s: FGS Logger Transaction failed, %d", __func__, err); return err; } @@ -224,7 +226,7 @@ public: data.writeInt32(appPid); status_t err = remote()->transact(LOG_FGS_API_STATE_CHANGED_TRANSACTION, data, &reply, IBinder::FLAG_ONEWAY); - if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) { + if (err != NO_ERROR) { ALOGD("%s: FGS Logger Transaction failed, %d", __func__, err); return err; } diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index 623e7b9139..1c1b6f30a4 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -38,6 +38,10 @@ #include "Utils.h" #include "binder_module.h" +#if (defined(__ANDROID__) || defined(__Fuchsia__)) && !defined(BINDER_WITH_KERNEL_IPC) +#error Android and Fuchsia are expected to have BINDER_WITH_KERNEL_IPC +#endif + #if LOG_NDEBUG #define IF_LOG_TRANSACTIONS() if (false) @@ -626,12 +630,22 @@ void IPCThreadState::flushCommands() { if (mProcess->mDriverFD < 0) return; - talkWithDriver(false); + + if (status_t res = talkWithDriver(false); res != OK) { + // TODO: we may want to abort for some of these cases + ALOGW("1st call to talkWithDriver returned error in flushCommands: %s", + statusToString(res).c_str()); + } + // The flush could have caused post-write refcount decrements to have // been executed, which in turn could result in BC_RELEASE/BC_DECREFS // being queued in mOut. So flush again, if we need to. if (mOut.dataSize() > 0) { - talkWithDriver(false); + if (status_t res = talkWithDriver(false); res != OK) { + // TODO: we may want to abort for some of these cases + ALOGW("2nd call to talkWithDriver returned error in flushCommands: %s", + statusToString(res).c_str()); + } } if (mOut.dataSize() > 0) { ALOGW("mOut.dataSize() > 0 after flushCommands()"); @@ -803,7 +817,11 @@ void IPCThreadState::joinThreadPool(bool isMain) mOut.writeInt32(BC_EXIT_LOOPER); mIsLooper = false; - talkWithDriver(false); + if (status_t res = talkWithDriver(false); res != OK) { + // TODO: we may want to abort for some of these cases + ALOGW("call to talkWithDriver in joinThreadPool returned error: %s, FD: %d", + statusToString(res).c_str(), mProcess->mDriverFD); + } size_t oldCount = mProcess->mCurrentThreads.fetch_sub(1); LOG_ALWAYS_FATAL_IF(oldCount == 0, "Threadpool thread count underflowed. Thread cannot exist and exit in " @@ -840,7 +858,7 @@ status_t IPCThreadState::handlePolledCommands() void IPCThreadState::stopProcess(bool /*immediate*/) { //ALOGI("**** STOPPING PROCESS"); - flushCommands(); + (void)flushCommands(); int fd = mProcess->mDriverFD; mProcess->mDriverFD = -1; close(fd); @@ -1215,7 +1233,7 @@ status_t IPCThreadState::talkWithDriver(bool doReceive) std::string message = logStream.str(); ALOGI("%s", message.c_str()); } -#if defined(__ANDROID__) +#if defined(BINDER_WITH_KERNEL_IPC) if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) err = NO_ERROR; else @@ -1494,7 +1512,14 @@ status_t IPCThreadState::executeCommand(int32_t cmd) buffer.setDataSize(0); constexpr uint32_t kForwardReplyFlags = TF_CLEAR_BUF; - sendReply(reply, (tr.flags & kForwardReplyFlags)); + + // TODO: we may want to abort if there is an error here, or return as 'error' + // from this function, but the impact needs to be measured + status_t error2 = sendReply(reply, (tr.flags & kForwardReplyFlags)); + if (error2 != OK) { + ALOGE("error in sendReply for synchronous call: %s", + statusToString(error2).c_str()); + } } else { if (error != OK) { std::ostringstream logStream; @@ -1604,7 +1629,7 @@ void IPCThreadState::threadDestructor(void *st) IPCThreadState* const self = static_cast<IPCThreadState*>(st); if (self) { self->flushCommands(); -#if defined(__ANDROID__) +#if defined(BINDER_WITH_KERNEL_IPC) if (self->mProcess->mDriverFD >= 0) { ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0); } @@ -1620,7 +1645,7 @@ status_t IPCThreadState::getProcessFreezeInfo(pid_t pid, uint32_t *sync_received binder_frozen_status_info info = {}; info.pid = pid; -#if defined(__ANDROID__) +#if defined(BINDER_WITH_KERNEL_IPC) if (ioctl(self()->mProcess->mDriverFD, BINDER_GET_FROZEN_INFO, &info) < 0) ret = -errno; #endif @@ -1639,7 +1664,7 @@ status_t IPCThreadState::freeze(pid_t pid, bool enable, uint32_t timeout_ms) { info.timeout_ms = timeout_ms; -#if defined(__ANDROID__) +#if defined(BINDER_WITH_KERNEL_IPC) if (ioctl(self()->mProcess->mDriverFD, BINDER_FREEZE, &info) < 0) ret = -errno; #endif @@ -1657,7 +1682,7 @@ void IPCThreadState::logExtendedError() { if (!ProcessState::isDriverFeatureEnabled(ProcessState::DriverFeature::EXTENDED_ERROR)) return; -#if defined(__ANDROID__) +#if defined(BINDER_WITH_KERNEL_IPC) if (ioctl(self()->mProcess->mDriverFD, BINDER_GET_EXTENDED_ERROR, &ee) < 0) { ALOGE("Failed to get extended error: %s", strerror(errno)); return; diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 5c72ed3197..c9ca646472 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -43,7 +43,11 @@ #include <binder/IPermissionController.h> #endif -#ifdef __ANDROID__ +#if !(defined(__ANDROID__) || defined(__FUCHSIA)) +#define BINDER_SERVICEMANAGEMENT_DELEGATION_SUPPORT +#endif + +#if !defined(BINDER_SERVICEMANAGEMENT_DELEGATION_SUPPORT) #include <cutils/properties.h> #else #include "ServiceManagerHost.h" @@ -624,7 +628,7 @@ sp<IBinder> CppBackendShim::getService(const String16& name) const { sp<IBinder> CppBackendShim::checkService(const String16& name) const { Service ret; - if (!mUnifiedServiceManager->checkService(String8(name).c_str(), &ret).isOk()) { + if (!mUnifiedServiceManager->checkService2(String8(name).c_str(), &ret).isOk()) { return nullptr; } return ret.get<Service::Tag::serviceWithMetadata>().service; @@ -902,7 +906,7 @@ std::vector<IServiceManager::ServiceDebugInfo> CppBackendShim::getServiceDebugIn return ret; } -#ifndef __ANDROID__ +#if defined(BINDER_SERVICEMANAGEMENT_DELEGATION_SUPPORT) // CppBackendShim for host. Implements the old libbinder android::IServiceManager API. // The internal implementation of the AIDL interface android::os::IServiceManager calls into // on-device service manager. diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 0b7cd8154d..777c22a63e 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -299,8 +299,13 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) { obj.handle = handle; obj.cookie = 0; } else { +#if __linux__ int policy = local->getMinSchedulerPolicy(); int priority = local->getMinSchedulerPriority(); +#else + int policy = 0; + int priority = 0; +#endif if (policy != 0 || priority != 0) { // override value, since it is set explicitly @@ -616,6 +621,7 @@ status_t Parcel::appendFrom(const Parcel* parcel, size_t offset, size_t len) { } #else LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time"); + (void)kernelFields; return INVALID_OPERATION; #endif // BINDER_WITH_KERNEL_IPC } else { @@ -797,6 +803,7 @@ std::vector<int> Parcel::debugReadAllFileDescriptors() const { setDataPosition(initPosition); #else LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time"); + (void)kernelFields; #endif } else if (const auto* rpcFields = maybeRpcFields(); rpcFields && rpcFields->mFds) { for (const auto& fd : *rpcFields->mFds) { @@ -839,9 +846,10 @@ status_t Parcel::hasBindersInRange(size_t offset, size_t len, bool* result) cons } #else LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time"); + (void)kernelFields; return INVALID_OPERATION; #endif // BINDER_WITH_KERNEL_IPC - } else if (const auto* rpcFields = maybeRpcFields()) { + } else if (maybeRpcFields()) { return INVALID_OPERATION; } return NO_ERROR; @@ -879,6 +887,7 @@ status_t Parcel::hasFileDescriptorsInRange(size_t offset, size_t len, bool* resu } #else LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time"); + (void)kernelFields; return INVALID_OPERATION; #endif // BINDER_WITH_KERNEL_IPC } else if (const auto* rpcFields = maybeRpcFields()) { @@ -971,6 +980,7 @@ status_t Parcel::writeInterfaceToken(const char16_t* str, size_t len) { writeInt32(kHeader); #else // BINDER_WITH_KERNEL_IPC LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time"); + (void)kernelFields; return INVALID_OPERATION; #endif // BINDER_WITH_KERNEL_IPC } @@ -1061,6 +1071,7 @@ bool Parcel::enforceInterface(const char16_t* interface, #else // BINDER_WITH_KERNEL_IPC LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time"); (void)threadState; + (void)kernelFields; return false; #endif // BINDER_WITH_KERNEL_IPC } @@ -1293,10 +1304,6 @@ status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<unique_fd>& v status_t Parcel::writeUniqueFileDescriptorVector(const std::optional<std::vector<unique_fd>>& val) { return writeData(val); } -status_t Parcel::writeUniqueFileDescriptorVector( - const std::unique_ptr<std::vector<unique_fd>>& val) { - return writeData(val); -} status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val) { return writeData(val); } status_t Parcel::writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val) { return writeData(val); } @@ -1352,10 +1359,6 @@ status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) co status_t Parcel::readUniqueFileDescriptorVector(std::optional<std::vector<unique_fd>>* val) const { return readData(val); } -status_t Parcel::readUniqueFileDescriptorVector( - std::unique_ptr<std::vector<unique_fd>>* val) const { - return readData(val); -} status_t Parcel::readUniqueFileDescriptorVector(std::vector<unique_fd>* val) const { return readData(val); } @@ -2696,6 +2699,7 @@ void Parcel::closeFileDescriptors(size_t newObjectsSize) { #else // BINDER_WITH_KERNEL_IPC (void)newObjectsSize; LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time"); + (void)kernelFields; #endif // BINDER_WITH_KERNEL_IPC } else if (auto* rpcFields = maybeRpcFields()) { rpcFields->mFds.reset(); @@ -3397,14 +3401,6 @@ void Parcel::scanForFds() const { } #ifdef BINDER_WITH_KERNEL_IPC -size_t Parcel::getBlobAshmemSize() const -{ - // This used to return the size of all blobs that were written to ashmem, now we're returning - // the ashmem currently referenced by this Parcel, which should be equivalent. - // TODO(b/202029388): Remove method once ABI can be changed. - return getOpenAshmemSize(); -} - size_t Parcel::getOpenAshmemSize() const { auto* kernelFields = maybeKernelFields(); diff --git a/libs/binder/PersistableBundle.cpp b/libs/binder/PersistableBundle.cpp index abb6612a1c..99f9726c5e 100644 --- a/libs/binder/PersistableBundle.cpp +++ b/libs/binder/PersistableBundle.cpp @@ -119,6 +119,9 @@ status_t PersistableBundle::writeToParcel(Parcel* parcel) const { } RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(length))); parcel->setDataPosition(end_pos); + // write mHasIntent to be consistent with BaseBundle.writeToBundle. But it would always be + // false since PersistableBundle won't contain an intent. + RETURN_IF_FAILED(parcel->writeBool(false)); return NO_ERROR; } @@ -473,6 +476,8 @@ status_t PersistableBundle::readFromParcelInner(const Parcel* parcel, size_t len } } } + // result intentional ignored since it will always be false; + RETURN_IF_FAILED(parcel->readBool()); return NO_ERROR; } diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index 0e1e9b4127..0bec37999b 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -48,6 +48,10 @@ #define DEFAULT_MAX_BINDER_THREADS 15 #define DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION 1 +#if defined(__ANDROID__) || defined(__Fuchsia__) +#define EXPECT_BINDER_OPEN_SUCCESS +#endif + #ifdef __ANDROID_VNDK__ const char* kDefaultDriver = "/dev/vndbinder"; #else @@ -613,7 +617,7 @@ ProcessState::ProcessState(const char* driver) } } -#ifdef __ANDROID__ +#if defined(EXPECT_BINDER_OPEN_SUCCESS) LOG_ALWAYS_FATAL_IF(!opened.ok(), "Binder driver '%s' could not be opened. Error: %s. Terminating.", driver, error.c_str()); diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp index 16023ffa82..1f3a45a6df 100644 --- a/libs/binder/RpcSession.cpp +++ b/libs/binder/RpcSession.cpp @@ -188,7 +188,9 @@ status_t RpcSession::setupInetClient(const char* addr, unsigned int port) { } status_t RpcSession::setupPreconnectedClient(unique_fd fd, std::function<unique_fd()>&& request) { - return setupClient([&](const std::vector<uint8_t>& sessionId, bool incoming) -> status_t { + return setupClient([&, fd = std::move(fd), + request = std::move(request)](const std::vector<uint8_t>& sessionId, + bool incoming) mutable -> status_t { if (!fd.ok()) { fd = request(); if (!fd.ok()) return BAD_VALUE; @@ -476,8 +478,10 @@ sp<RpcServer> RpcSession::server() { return server; } -status_t RpcSession::setupClient(const std::function<status_t(const std::vector<uint8_t>& sessionId, - bool incoming)>& connectAndInit) { +template <typename Fn, + typename /* = std::enable_if_t<std::is_invocable_r_v< + status_t, Fn, const std::vector<uint8_t>&, bool>> */> +status_t RpcSession::setupClient(Fn&& connectAndInit) { { RpcMutexLockGuard _l(mMutex); LOG_ALWAYS_FATAL_IF(mStartedSetup, "Must only setup session once"); diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp index fe6e1a3318..03d974d186 100644 --- a/libs/binder/RpcState.cpp +++ b/libs/binder/RpcState.cpp @@ -23,6 +23,7 @@ #include <binder/IPCThreadState.h> #include <binder/RpcServer.h> +#include "Constants.h" #include "Debug.h" #include "RpcWireFormat.h" #include "Utils.h" @@ -337,6 +338,8 @@ std::string RpcState::BinderNode::toString() const { } RpcState::CommandData::CommandData(size_t size) : mSize(size) { + if (size == 0) return; + // The maximum size for regular binder is 1MB for all concurrent // transactions. A very small proportion of transactions are even // larger than a page, but we need to avoid allocating too much @@ -348,11 +351,11 @@ RpcState::CommandData::CommandData(size_t size) : mSize(size) { // transaction (in some cases, additional fixed size amounts are added), // though for rough consistency, we should avoid cases where this data type // is used for multiple dynamic allocations for a single transaction. - constexpr size_t kMaxTransactionAllocation = 100 * 1000; - if (size == 0) return; - if (size > kMaxTransactionAllocation) { - ALOGW("Transaction requested too much data allocation %zu", size); + if (size > binder::kRpcTransactionLimitBytes) { + ALOGE("Transaction requested too much data allocation: %zu bytes, failing.", size); return; + } else if (size > binder::kLogTransactionsOverBytes) { + ALOGW("Transaction too large: inefficient and in danger of breaking: %zu bytes.", size); } mData.reset(new (std::nothrow) uint8_t[size]); } diff --git a/libs/binder/RpcTransportTipcAndroid.cpp b/libs/binder/RpcTransportTipcAndroid.cpp index 3819fb6472..14c0bde7c5 100644 --- a/libs/binder/RpcTransportTipcAndroid.cpp +++ b/libs/binder/RpcTransportTipcAndroid.cpp @@ -21,6 +21,7 @@ #include <log/log.h> #include <poll.h> #include <trusty/tipc.h> +#include <type_traits> #include "FdTrigger.h" #include "RpcState.h" @@ -32,6 +33,9 @@ using android::binder::unique_fd; namespace android { +// Corresponds to IPC_MAX_MSG_HANDLES in the Trusty kernel +constexpr size_t kMaxTipcHandles = 8; + // RpcTransport for writing Trusty IPC clients in Android. class RpcTransportTipcAndroid : public RpcTransport { public: @@ -78,12 +82,28 @@ public: FdTrigger* fdTrigger, iovec* iovs, int niovs, const std::optional<SmallFunction<status_t()>>& altPoll, const std::vector<std::variant<unique_fd, borrowed_fd>>* ancillaryFds) override { + bool sentFds = false; auto writeFn = [&](iovec* iovs, size_t niovs) -> ssize_t { - // TODO: send ancillaryFds. For now, we just abort if anyone tries - // to send any. - LOG_ALWAYS_FATAL_IF(ancillaryFds != nullptr && !ancillaryFds->empty(), - "File descriptors are not supported on Trusty yet"); - return TEMP_FAILURE_RETRY(tipc_send(mSocket.fd.get(), iovs, niovs, nullptr, 0)); + trusty_shm shms[kMaxTipcHandles] = {{0}}; + ssize_t shm_count = 0; + + if (!sentFds && ancillaryFds != nullptr && !ancillaryFds->empty()) { + if (ancillaryFds->size() > kMaxTipcHandles) { + ALOGE("Too many file descriptors for TIPC: %zu", ancillaryFds->size()); + errno = EINVAL; + return -1; + } + for (const auto& fdVariant : *ancillaryFds) { + shms[shm_count++] = {std::visit([](const auto& fd) { return fd.get(); }, + fdVariant), + TRUSTY_SEND_SECURE_OR_SHARE}; + } + } + + auto ret = TEMP_FAILURE_RETRY(tipc_send(mSocket.fd.get(), iovs, niovs, + (shm_count == 0) ? nullptr : shms, shm_count)); + sentFds |= ret >= 0; + return ret; }; status_t status = interruptableReadOrWrite(mSocket, fdTrigger, iovs, niovs, writeFn, diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING index 9e5e79f89b..4332f8ae79 100644 --- a/libs/binder/TEST_MAPPING +++ b/libs/binder/TEST_MAPPING @@ -37,6 +37,9 @@ "name": "binderStabilityTest" }, { + "name": "binderStabilityIntegrationTest" + }, + { "name": "binderRpcWireProtocolTest" }, { diff --git a/libs/binder/aidl/android/content/pm/OWNERS b/libs/binder/aidl/android/content/pm/OWNERS index 31005184bf..2617a16f69 100644 --- a/libs/binder/aidl/android/content/pm/OWNERS +++ b/libs/binder/aidl/android/content/pm/OWNERS @@ -1,5 +1,4 @@ +michaelwr@google.com narayan@google.com patb@google.com -svetoslavganov@google.com -toddke@google.com -patb@google.com
\ No newline at end of file +schfan@google.com diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl index 69edef86aa..6539238ce7 100644 --- a/libs/binder/aidl/android/os/IServiceManager.aidl +++ b/libs/binder/aidl/android/os/IServiceManager.aidl @@ -83,11 +83,20 @@ interface IServiceManager { /** * Retrieve an existing service called @a name from the service + * manager. Non-blocking. Returns null if the service does not exist. + * + * @deprecated TODO(b/355394904): Use checkService2 instead. This does not + * return metadata that is included in ServiceWithMetadata + */ + @UnsupportedAppUsage + @nullable IBinder checkService(@utf8InCpp String name); + + /** + * Retrieve an existing service called @a name from the service * manager. Non-blocking. Returns null if the service does not * exist. */ - @UnsupportedAppUsage - Service checkService(@utf8InCpp String name); + Service checkService2(@utf8InCpp String name); /** * Place a new @a service called @a name into the service diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h index 7518044ce6..935bd8dbc6 100644 --- a/libs/binder/include/binder/BpBinder.h +++ b/libs/binder/include/binder/BpBinder.h @@ -104,6 +104,7 @@ public: // Stop the current recording. LIBBINDER_EXPORTED status_t stopRecordingBinder(); + // Note: This class is not thread safe so protect uses of it when necessary class ObjectManager { public: ObjectManager(); @@ -116,8 +117,6 @@ public: sp<IBinder> lookupOrCreateWeak(const void* objectID, IBinder::object_make_func make, const void* makeArgs); - void kill(); - private: ObjectManager(const ObjectManager&); ObjectManager& operator=(const ObjectManager&); @@ -224,7 +223,7 @@ private: volatile int32_t mObitsSent; Vector<Obituary>* mObituaries; std::unique_ptr<FrozenStateChange> mFrozen; - ObjectManager mObjects; + ObjectManager mObjectMgr; mutable String16 mDescriptorCache; int32_t mTrackedUid; diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h index bb45ad2ad5..993ad82b96 100644 --- a/libs/binder/include/binder/IInterface.h +++ b/libs/binder/include/binder/IInterface.h @@ -263,7 +263,6 @@ constexpr const char* const kManualInterfaces[] = { "android.utils.IMemory", "android.utils.IMemoryHeap", "com.android.car.procfsinspector.IProcfsInspector", - "com.android.internal.app.IAppOpsCallback", "com.android.internal.app.IAppOpsService", "com.android.internal.app.IBatteryStats", "com.android.internal.os.IResultReceiver", diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index 69a73d415e..6c4c6fe573 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -383,9 +383,6 @@ public: LIBBINDER_EXPORTED status_t writeUniqueFileDescriptorVector(const std::optional<std::vector<binder::unique_fd>>& val); LIBBINDER_EXPORTED status_t - writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<binder::unique_fd>>& val) - __attribute__((deprecated("use std::optional version instead"))); - LIBBINDER_EXPORTED status_t writeUniqueFileDescriptorVector(const std::vector<binder::unique_fd>& val); // WARNING: deprecated and incompatible with AIDL. You should use Parcelable @@ -630,9 +627,6 @@ public: LIBBINDER_EXPORTED status_t readUniqueFileDescriptorVector(std::optional<std::vector<binder::unique_fd>>* val) const; LIBBINDER_EXPORTED status_t - readUniqueFileDescriptorVector(std::unique_ptr<std::vector<binder::unique_fd>>* val) const - __attribute__((deprecated("use std::optional version instead"))); - LIBBINDER_EXPORTED status_t readUniqueFileDescriptorVector(std::vector<binder::unique_fd>* val) const; // WARNING: deprecated and incompatible with AIDL. You should use Parcelable @@ -1494,14 +1488,15 @@ public: * Note: for historical reasons, this does not include ashmem memory which * is referenced by this Parcel, but which this parcel doesn't own (e.g. * writeFileDescriptor is called without 'takeOwnership' true). + * + * WARNING: you should not use this, but rather, unparcel, and inspect + * each FD independently. This counts ashmem size, but there may be + * other resources used for non-ashmem FDs, such as other types of + * shared memory, files, etc.. */ LIBBINDER_EXPORTED size_t getOpenAshmemSize() const; private: - // TODO(b/202029388): Remove 'getBlobAshmemSize' once no prebuilts reference - // this - LIBBINDER_EXPORTED size_t getBlobAshmemSize() const; - // Needed so that we can save object metadata to the disk friend class android::binder::debug::RecordedTransaction; }; diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h index af37bf29a4..c9f92da009 100644 --- a/libs/binder/include/binder/RpcSession.h +++ b/libs/binder/include/binder/RpcSession.h @@ -25,6 +25,7 @@ #include <map> #include <optional> +#include <type_traits> #include <vector> namespace android { @@ -291,9 +292,14 @@ private: // join on thread passed to preJoinThreadOwnership static void join(sp<RpcSession>&& session, PreJoinSetupResult&& result); - [[nodiscard]] status_t setupClient( - const std::function<status_t(const std::vector<uint8_t>& sessionId, bool incoming)>& - connectAndInit); + // This is a workaround to support move-only functors. + // TODO: use std::move_only_function when it becomes available. + template <typename Fn, + // Fn must be a callable type taking (const std::vector<uint8_t>&, bool) and returning + // status_t + typename = std::enable_if_t< + std::is_invocable_r_v<status_t, Fn, const std::vector<uint8_t>&, bool>>> + [[nodiscard]] status_t setupClient(Fn&& connectAndInit); [[nodiscard]] status_t setupSocketClient(const RpcSocketAddress& address); [[nodiscard]] status_t setupOneSocketConnection(const RpcSocketAddress& address, const std::vector<uint8_t>& sessionId, diff --git a/libs/binder/include/binder/RpcThreads.h b/libs/binder/include/binder/RpcThreads.h index 99fa6b8b29..51b9716bb1 100644 --- a/libs/binder/include/binder/RpcThreads.h +++ b/libs/binder/include/binder/RpcThreads.h @@ -20,6 +20,7 @@ #include <condition_variable> #include <functional> #include <memory> +#include <mutex> #include <thread> #include <binder/Common.h> diff --git a/libs/binder/include/binder/SafeInterface.h b/libs/binder/include/binder/SafeInterface.h index bcbd14f9d4..e848385418 100644 --- a/libs/binder/include/binder/SafeInterface.h +++ b/libs/binder/include/binder/SafeInterface.h @@ -79,7 +79,7 @@ public: template <typename T> typename std::enable_if<std::is_base_of<Flattenable<T>, T>::value, status_t>::type read( const Parcel& parcel, sp<T>* t) const { - *t = new T{}; + *t = sp<T>::make(); return callParcel("read(sp<Flattenable>)", [&]() { return parcel.read(*(t->get())); }); } template <typename T> diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h index cafb8aa04b..bfe0a5af9c 100644 --- a/libs/binder/include/binder/Stability.h +++ b/libs/binder/include/binder/Stability.h @@ -20,6 +20,8 @@ #include <binder/IBinder.h> #include <string> +class BinderStabilityIntegrationTest_ExpectedStabilityForItsPartition_Test; + namespace android { class BpBinder; @@ -127,6 +129,8 @@ private: // through Parcel) friend ::android::ProcessState; + friend ::BinderStabilityIntegrationTest_ExpectedStabilityForItsPartition_Test; + static void tryMarkCompilationUnit(IBinder* binder); // Currently, we use int16_t for Level so that it can fit in BBinder. @@ -156,11 +160,11 @@ private: uint32_t flags); // get stability information as encoded on the wire - static int16_t getRepr(IBinder* binder); + LIBBINDER_EXPORTED static int16_t getRepr(IBinder* binder); // whether a transaction on binder is allowed, if the transaction // is done from a context with a specific stability level - static bool check(int16_t provided, Level required); + LIBBINDER_EXPORTED static bool check(int16_t provided, Level required); static bool isDeclaredLevel(int32_t level); static std::string levelString(int32_t level); diff --git a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp index 48c0ea636b..1949cbb039 100644 --- a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp +++ b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp @@ -134,9 +134,14 @@ AIBinder* ARpcSession_setupInet(ARpcSession* session, const char* address, unsig // // param will be passed to requestFd. Callers can use param to pass contexts to // the requestFd function. +// +// paramDeleteFd will be called when requestFd and param are no longer in use. +// Callers can pass a function deleting param if necessary. Callers can set +// paramDeleteFd to null if callers doesn't need to clean up param. AIBinder* ARpcSession_setupPreconnectedClient(ARpcSession* session, int (*requestFd)(void* param), - void* param); + void* param, + void (*paramDeleteFd)(void* param)); // Sets the file descriptor transport mode for this session. void ARpcSession_setFileDescriptorTransportMode(ARpcSession* session, diff --git a/libs/binder/libbinder_rpc_unstable.cpp b/libs/binder/libbinder_rpc_unstable.cpp index 64b1be25d2..8177fb07db 100644 --- a/libs/binder/libbinder_rpc_unstable.cpp +++ b/libs/binder/libbinder_rpc_unstable.cpp @@ -248,9 +248,18 @@ AIBinder* ARpcSession_setupInet(ARpcSession* handle, const char* address, unsign #endif // __TRUSTY__ AIBinder* ARpcSession_setupPreconnectedClient(ARpcSession* handle, int (*requestFd)(void* param), - void* param) { + void* param, void (*paramDeleteFd)(void* param)) { auto session = handleToStrongPointer<RpcSession>(handle); - auto request = [=] { return unique_fd{requestFd(param)}; }; + auto deleter = [=](void* param) { + if (paramDeleteFd) { + paramDeleteFd(param); + } + }; + // TODO: use unique_ptr once setupPreconnectedClient uses std::move_only_function. + std::shared_ptr<void> sharedParam(param, deleter); + auto request = [=, sharedParam = std::move(sharedParam)] { + return unique_fd{requestFd(sharedParam.get())}; + }; if (status_t status = session->setupPreconnectedClient(unique_fd{}, request); status != OK) { ALOGE("Failed to set up preconnected client. error: %s", statusToString(status).c_str()); return nullptr; diff --git a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h index 89f21dda21..783e11f0e9 100644 --- a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h +++ b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h @@ -62,6 +62,8 @@ __attribute__((weak, warn_unused_result)) const char* AIBinder_getCallingSid() _ * This must be called before the object is sent to another process. * Aborts on invalid values. Not thread safe. * + * This overrides the setting in ABinderProcess_disableBackgroundScheduling. + * * \param binder local server binder to set the policy for * \param policy scheduler policy as defined in linux UAPI * \param priority priority. [-20..19] for SCHED_NORMAL, [1..99] for RT diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h index f5df8d5c2f..2c2e2c8856 100644 --- a/libs/binder/ndk/include_platform/android/binder_manager.h +++ b/libs/binder/ndk/include_platform/android/binder_manager.h @@ -30,10 +30,14 @@ enum AServiceManager_AddServiceFlag : uint32_t { * not be added with this flag for privacy concerns. */ ADD_SERVICE_ALLOW_ISOLATED = 1 << 0, + /** + * Allows services to dump sections according to priorities and format + */ ADD_SERVICE_DUMP_FLAG_PRIORITY_CRITICAL = 1 << 1, ADD_SERVICE_DUMP_FLAG_PRIORITY_HIGH = 1 << 2, ADD_SERVICE_DUMP_FLAG_PRIORITY_NORMAL = 1 << 3, ADD_SERVICE_DUMP_FLAG_PRIORITY_DEFAULT = 1 << 4, + ADD_SERVICE_DUMP_FLAG_PROTO = 1 << 5, // All other bits are reserved for internal usage }; diff --git a/libs/binder/ndk/include_platform/android/binder_process.h b/libs/binder/ndk/include_platform/android/binder_process.h index 6aff994a15..2432099d6e 100644 --- a/libs/binder/ndk/include_platform/android/binder_process.h +++ b/libs/binder/ndk/include_platform/android/binder_process.h @@ -75,6 +75,19 @@ bool ABinderProcess_isThreadPoolStarted(void); void ABinderProcess_joinThreadPool(void); /** + * Disables (or enables) background scheduling. + * + * By default, binder threads execute at a lower priority. However, this can cause + * priority inversion, so it is recommended to be disabled in high priority + * or in system processes. + * + * See also AIBinder_setMinSchedulerPolicy, which overrides this setting. + * + * \param disable whether to disable background scheduling + */ +void ABinderProcess_disableBackgroundScheduling(bool disable); + +/** * This gives you an fd to wait on. Whenever data is available on the fd, * ABinderProcess_handlePolledCommands can be called to handle binder queries. * This is expected to be used in a single threaded process which waits on diff --git a/libs/binder/ndk/include_platform/android/binder_stability.h b/libs/binder/ndk/include_platform/android/binder_stability.h index 089c775eca..80502056ee 100644 --- a/libs/binder/ndk/include_platform/android/binder_stability.h +++ b/libs/binder/ndk/include_platform/android/binder_stability.h @@ -27,6 +27,10 @@ constexpr binder_flags_t FLAG_PRIVATE_VENDOR = 0x10000000; #if defined(__ANDROID_VENDOR__) +#if defined(__ANDROID_PRODUCT__) +#error "build bug: product is not part of the vendor half of the Treble system/vendor split" +#endif + /** * Private addition to binder_flag_t. */ diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt index a63716522e..d4eb8c7579 100644 --- a/libs/binder/ndk/libbinder_ndk.map.txt +++ b/libs/binder/ndk/libbinder_ndk.map.txt @@ -229,6 +229,7 @@ LIBBINDER_NDK_PLATFORM { AIBinder_fromPlatformBinder*; AIBinder_toPlatformBinder*; AParcel_viewPlatformParcel*; + ABinderProcess_disableBackgroundScheduling; }; local: *; diff --git a/libs/binder/ndk/process.cpp b/libs/binder/ndk/process.cpp index 0072ac3d3e..bcdb9594fa 100644 --- a/libs/binder/ndk/process.cpp +++ b/libs/binder/ndk/process.cpp @@ -36,6 +36,10 @@ void ABinderProcess_joinThreadPool(void) { IPCThreadState::self()->joinThreadPool(); } +void ABinderProcess_disableBackgroundScheduling(bool disable) { + IPCThreadState::disableBackgroundScheduling(disable); +} + binder_status_t ABinderProcess_setupPolling(int* fd) { return IPCThreadState::self()->setupPolling(fd); } diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp index d6ac4acc29..14bc5d2b75 100644 --- a/libs/binder/ndk/service_manager.cpp +++ b/libs/binder/ndk/service_manager.cpp @@ -63,6 +63,9 @@ binder_exception_t AServiceManager_addServiceWithFlags(AIBinder* binder, const c if (flags & AServiceManager_AddServiceFlag::ADD_SERVICE_DUMP_FLAG_PRIORITY_DEFAULT) { dumpFlags |= IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT; } + if (flags & AServiceManager_AddServiceFlag::ADD_SERVICE_DUMP_FLAG_PROTO) { + dumpFlags |= IServiceManager::DUMP_FLAG_PROTO; + } if (dumpFlags == 0) { dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT; } diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp index 8404a48c26..adef9ea64b 100644 --- a/libs/binder/rust/Android.bp +++ b/libs/binder/rust/Android.bp @@ -16,6 +16,7 @@ rust_library { "libdowncast_rs", "liblibc", "liblog_rust", + "libzerocopy", ], host_supported: true, vendor_available: true, @@ -205,6 +206,7 @@ rust_test { "libdowncast_rs", "liblibc", "liblog_rust", + "libzerocopy", ], } diff --git a/libs/binder/rust/rpcbinder/Android.bp b/libs/binder/rust/rpcbinder/Android.bp index 4036551ef3..46651ceb48 100644 --- a/libs/binder/rust/rpcbinder/Android.bp +++ b/libs/binder/rust/rpcbinder/Android.bp @@ -26,6 +26,7 @@ rust_library { ], visibility: [ "//device/google/cuttlefish/shared/minidroid/sample", + "//hardware/interfaces/security/see:__subpackages__", "//packages/modules/Virtualization:__subpackages__", ], apex_available: [ diff --git a/libs/binder/rust/rpcbinder/src/lib.rs b/libs/binder/rust/rpcbinder/src/lib.rs index 7e5c9ddc35..774bb21efe 100644 --- a/libs/binder/rust/rpcbinder/src/lib.rs +++ b/libs/binder/rust/rpcbinder/src/lib.rs @@ -20,6 +20,8 @@ mod server; mod session; pub use server::RpcServer; +#[cfg(target_os = "trusty")] +pub use server::RpcServerConnection; #[cfg(not(target_os = "trusty"))] pub use server::RpcServerRef; pub use session::{FileDescriptorTransportMode, RpcSession, RpcSessionRef}; diff --git a/libs/binder/rust/rpcbinder/src/session.rs b/libs/binder/rust/rpcbinder/src/session.rs index 09688a21a7..411b9de849 100644 --- a/libs/binder/rust/rpcbinder/src/session.rs +++ b/libs/binder/rust/rpcbinder/src/session.rs @@ -195,11 +195,13 @@ impl RpcSessionRef { /// take ownership of) file descriptors already connected to it. pub fn setup_preconnected_client<T: FromIBinder + ?Sized>( &self, - mut request_fd: impl FnMut() -> Option<RawFd>, + request_fd: impl FnMut() -> Option<RawFd>, ) -> Result<Strong<T>, StatusCode> { - // Double reference the factory because trait objects aren't FFI safe. - let mut request_fd_ref: RequestFd = &mut request_fd; - let param = &mut request_fd_ref as *mut RequestFd as *mut c_void; + // Trait objects aren't FFI safe, so *mut c_void can't be converted back to + // *mut dyn FnMut() -> Option<RawFd>>. Double box the factory to make it possible to get + // the factory from *mut c_void (to *mut Box<dyn<...>>) in the callbacks. + let request_fd_box: Box<dyn FnMut() -> Option<RawFd>> = Box::new(request_fd); + let param = Box::into_raw(Box::new(request_fd_box)) as *mut c_void; // SAFETY: AIBinder returned by RpcPreconnectedClient has correct reference count, and the // ownership can be safely taken by new_spibinder. RpcPreconnectedClient does not take ownership @@ -209,6 +211,7 @@ impl RpcSessionRef { self.as_ptr(), Some(request_fd_wrapper), param, + Some(param_delete_fd_wrapper), )) }; Self::get_interface(service) @@ -225,13 +228,18 @@ impl RpcSessionRef { } } -type RequestFd<'a> = &'a mut dyn FnMut() -> Option<RawFd>; - unsafe extern "C" fn request_fd_wrapper(param: *mut c_void) -> c_int { - let request_fd_ptr = param as *mut RequestFd; + let request_fd_ptr = param as *mut Box<dyn FnMut() -> Option<RawFd>>; // SAFETY: This is only ever called by RpcPreconnectedClient, within the lifetime of the // BinderFdFactory reference, with param being a properly aligned non-null pointer to an // initialized instance. let request_fd = unsafe { request_fd_ptr.as_mut().unwrap() }; request_fd().unwrap_or(-1) } + +unsafe extern "C" fn param_delete_fd_wrapper(param: *mut c_void) { + // SAFETY: This is only ever called by RpcPreconnectedClient, with param being the + // pointer returned from Box::into_raw. + let request_fd_box = unsafe { Box::from_raw(param as *mut Box<dyn FnMut() -> Option<RawFd>>) }; + drop(request_fd_box); +} diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs index 8c0501ba2f..6a8a69843a 100644 --- a/libs/binder/rust/src/binder.rs +++ b/libs/binder/rust/src/binder.rs @@ -1201,5 +1201,45 @@ macro_rules! declare_binder_enum { Ok(v.map(|v| v.into_iter().map(Self).collect())) } } + + impl std::ops::BitOr for $enum { + type Output = Self; + fn bitor(self, rhs: Self) -> Self { + Self(self.0 | rhs.0) + } + } + + impl std::ops::BitOrAssign for $enum { + fn bitor_assign(&mut self, rhs: Self) { + self.0 = self.0 | rhs.0; + } + } + + impl std::ops::BitAnd for $enum { + type Output = Self; + fn bitand(self, rhs: Self) -> Self { + Self(self.0 & rhs.0) + } + } + + impl std::ops::BitAndAssign for $enum { + fn bitand_assign(&mut self, rhs: Self) { + self.0 = self.0 & rhs.0; + } + } + + impl std::ops::BitXor for $enum { + type Output = Self; + fn bitxor(self, rhs: Self) -> Self { + Self(self.0 ^ rhs.0) + } + } + + impl std::ops::BitXorAssign for $enum { + fn bitxor_assign(&mut self, rhs: Self) { + self.0 = self.0 ^ rhs.0; + } + } + }; } diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs index e08a76312d..0026f213f2 100644 --- a/libs/binder/rust/src/lib.rs +++ b/libs/binder/rust/src/lib.rs @@ -99,6 +99,8 @@ mod binder_async; mod error; mod native; mod parcel; +#[cfg(not(trusty))] +mod persistable_bundle; mod proxy; #[cfg(not(any(trusty, android_ndk)))] mod service; @@ -113,6 +115,8 @@ pub use crate::binder_async::{BinderAsyncPool, BoxFuture}; pub use binder::{BinderFeatures, FromIBinder, IBinder, Interface, Strong, Weak}; pub use error::{ExceptionCode, IntoBinderResult, Status, StatusCode}; pub use parcel::{ParcelFileDescriptor, Parcelable, ParcelableHolder}; +#[cfg(not(trusty))] +pub use persistable_bundle::{PersistableBundle, ValueType}; pub use proxy::{DeathRecipient, SpIBinder, WpIBinder}; #[cfg(not(any(trusty, android_ndk)))] pub use service::{ diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs index 485b0bdb0d..2d40ced2fd 100644 --- a/libs/binder/rust/src/parcel.rs +++ b/libs/binder/rust/src/parcel.rs @@ -184,7 +184,7 @@ unsafe impl AsNative<sys::AParcel> for Parcel { /// Safety: The `BorrowedParcel` constructors guarantee that a `BorrowedParcel` /// object will always contain a valid pointer to an `AParcel`. -unsafe impl<'a> AsNative<sys::AParcel> for BorrowedParcel<'a> { +unsafe impl AsNative<sys::AParcel> for BorrowedParcel<'_> { fn as_native(&self) -> *const sys::AParcel { self.ptr.as_ptr() } @@ -195,7 +195,7 @@ unsafe impl<'a> AsNative<sys::AParcel> for BorrowedParcel<'a> { } // Data serialization methods -impl<'a> BorrowedParcel<'a> { +impl BorrowedParcel<'_> { /// Data written to parcelable is zero'd before being deleted or reallocated. #[cfg(not(android_ndk))] pub fn mark_sensitive(&mut self) { @@ -334,7 +334,7 @@ impl<'a> BorrowedParcel<'a> { /// A segment of a writable parcel, used for [`BorrowedParcel::sized_write`]. pub struct WritableSubParcel<'a>(BorrowedParcel<'a>); -impl<'a> WritableSubParcel<'a> { +impl WritableSubParcel<'_> { /// Write a type that implements [`Serialize`] to the sub-parcel. pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> { parcelable.serialize(&mut self.0) @@ -440,7 +440,7 @@ impl Parcel { } // Data deserialization methods -impl<'a> BorrowedParcel<'a> { +impl BorrowedParcel<'_> { /// Attempt to read a type that implements [`Deserialize`] from this parcel. pub fn read<D: Deserialize>(&self) -> Result<D> { D::deserialize(self) @@ -565,7 +565,7 @@ pub struct ReadableSubParcel<'a> { end_position: i32, } -impl<'a> ReadableSubParcel<'a> { +impl ReadableSubParcel<'_> { /// Read a type that implements [`Deserialize`] from the sub-parcel. pub fn read<D: Deserialize>(&self) -> Result<D> { D::deserialize(&self.parcel) @@ -649,7 +649,7 @@ impl Parcel { } // Internal APIs -impl<'a> BorrowedParcel<'a> { +impl BorrowedParcel<'_> { pub(crate) fn write_binder(&mut self, binder: Option<&SpIBinder>) -> Result<()> { // Safety: `BorrowedParcel` always contains a valid pointer to an // `AParcel`. `AsNative` for `Option<SpIBinder`> will either return @@ -702,7 +702,7 @@ impl fmt::Debug for Parcel { } } -impl<'a> fmt::Debug for BorrowedParcel<'a> { +impl fmt::Debug for BorrowedParcel<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("BorrowedParcel").finish() } diff --git a/libs/binder/rust/src/persistable_bundle.rs b/libs/binder/rust/src/persistable_bundle.rs new file mode 100644 index 0000000000..8639c0d08c --- /dev/null +++ b/libs/binder/rust/src/persistable_bundle.rs @@ -0,0 +1,1076 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use crate::{ + binder::AsNative, + error::{status_result, StatusCode}, + impl_deserialize_for_unstructured_parcelable, impl_serialize_for_unstructured_parcelable, + parcel::{BorrowedParcel, UnstructuredParcelable}, +}; +use binder_ndk_sys::{ + APersistableBundle, APersistableBundle_delete, APersistableBundle_dup, + APersistableBundle_erase, APersistableBundle_getBoolean, APersistableBundle_getBooleanKeys, + APersistableBundle_getBooleanVector, APersistableBundle_getBooleanVectorKeys, + APersistableBundle_getDouble, APersistableBundle_getDoubleKeys, + APersistableBundle_getDoubleVector, APersistableBundle_getDoubleVectorKeys, + APersistableBundle_getInt, APersistableBundle_getIntKeys, APersistableBundle_getIntVector, + APersistableBundle_getIntVectorKeys, APersistableBundle_getLong, + APersistableBundle_getLongKeys, APersistableBundle_getLongVector, + APersistableBundle_getLongVectorKeys, APersistableBundle_getPersistableBundle, + APersistableBundle_getPersistableBundleKeys, APersistableBundle_getString, + APersistableBundle_getStringKeys, APersistableBundle_getStringVector, + APersistableBundle_getStringVectorKeys, APersistableBundle_isEqual, APersistableBundle_new, + APersistableBundle_putBoolean, APersistableBundle_putBooleanVector, + APersistableBundle_putDouble, APersistableBundle_putDoubleVector, APersistableBundle_putInt, + APersistableBundle_putIntVector, APersistableBundle_putLong, APersistableBundle_putLongVector, + APersistableBundle_putPersistableBundle, APersistableBundle_putString, + APersistableBundle_putStringVector, APersistableBundle_readFromParcel, APersistableBundle_size, + APersistableBundle_writeToParcel, APERSISTABLEBUNDLE_ALLOCATOR_FAILED, + APERSISTABLEBUNDLE_KEY_NOT_FOUND, +}; +use std::ffi::{c_char, c_void, CStr, CString, NulError}; +use std::ptr::{null_mut, slice_from_raw_parts_mut, NonNull}; +use zerocopy::FromZeros; + +/// A mapping from string keys to values of various types. +#[derive(Debug)] +pub struct PersistableBundle(NonNull<APersistableBundle>); + +impl PersistableBundle { + /// Creates a new `PersistableBundle`. + pub fn new() -> Self { + // SAFETY: APersistableBundle_new doesn't actually have any safety requirements. + let bundle = unsafe { APersistableBundle_new() }; + Self(NonNull::new(bundle).expect("Allocated APersistableBundle was null")) + } + + /// Returns the number of mappings in the bundle. + pub fn size(&self) -> usize { + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. + unsafe { APersistableBundle_size(self.0.as_ptr()) } + .try_into() + .expect("APersistableBundle_size returned a negative size") + } + + /// Removes any entry with the given key. + /// + /// Returns an error if the given key contains a NUL character, otherwise returns whether there + /// was any entry to remove. + pub fn remove(&mut self, key: &str) -> Result<bool, NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call. + Ok(unsafe { APersistableBundle_erase(self.0.as_ptr(), key.as_ptr()) != 0 }) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_bool(&mut self, key: &str, value: bool) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call. + unsafe { + APersistableBundle_putBoolean(self.0.as_ptr(), key.as_ptr(), value); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_int(&mut self, key: &str, value: i32) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call. + unsafe { + APersistableBundle_putInt(self.0.as_ptr(), key.as_ptr(), value); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_long(&mut self, key: &str, value: i64) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call. + unsafe { + APersistableBundle_putLong(self.0.as_ptr(), key.as_ptr(), value); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_double(&mut self, key: &str, value: f64) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call. + unsafe { + APersistableBundle_putDouble(self.0.as_ptr(), key.as_ptr(), value); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key or value contains a NUL character. + pub fn insert_string(&mut self, key: &str, value: &str) -> Result<(), NulError> { + let key = CString::new(key)?; + let value = CString::new(value)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `CStr::as_ptr` is guaranteed + // to be valid for the duration of this call. + unsafe { + APersistableBundle_putString(self.0.as_ptr(), key.as_ptr(), value.as_ptr()); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_bool_vec(&mut self, key: &str, value: &[bool]) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putBooleanVector( + self.0.as_ptr(), + key.as_ptr(), + value.as_ptr(), + value.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_int_vec(&mut self, key: &str, value: &[i32]) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putIntVector( + self.0.as_ptr(), + key.as_ptr(), + value.as_ptr(), + value.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_long_vec(&mut self, key: &str, value: &[i64]) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putLongVector( + self.0.as_ptr(), + key.as_ptr(), + value.as_ptr(), + value.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_double_vec(&mut self, key: &str, value: &[f64]) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putDoubleVector( + self.0.as_ptr(), + key.as_ptr(), + value.as_ptr(), + value.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_string_vec<'a, T: ToString + 'a>( + &mut self, + key: &str, + value: impl IntoIterator<Item = &'a T>, + ) -> Result<(), NulError> { + let key = CString::new(key)?; + // We need to collect the new `CString`s into something first so that they live long enough + // for their pointers to be valid for the `APersistableBundle_putStringVector` call below. + let c_strings = value + .into_iter() + .map(|s| CString::new(s.to_string())) + .collect::<Result<Vec<_>, NulError>>()?; + let char_pointers = c_strings.iter().map(|s| s.as_ptr()).collect::<Vec<_>>(); + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putStringVector( + self.0.as_ptr(), + key.as_ptr(), + char_pointers.as_ptr(), + char_pointers.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_persistable_bundle( + &mut self, + key: &str, + value: &PersistableBundle, + ) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the + // lifetime of the `PersistableBundle`s. The pointer returned by `CStr::as_ptr` is + // guaranteed to be valid for the duration of this call, and + // `APersistableBundle_putPersistableBundle` does a deep copy so that is all that is + // required. + unsafe { + APersistableBundle_putPersistableBundle( + self.0.as_ptr(), + key.as_ptr(), + value.0.as_ptr(), + ); + } + Ok(()) + } + + /// Gets the boolean value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_bool(&self, key: &str) -> Result<Option<bool>, NulError> { + let key = CString::new(key)?; + let mut value = false; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call. The value pointer must be valid because it + // comes from a reference. + if unsafe { APersistableBundle_getBoolean(self.0.as_ptr(), key.as_ptr(), &mut value) } { + Ok(Some(value)) + } else { + Ok(None) + } + } + + /// Gets the i32 value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_int(&self, key: &str) -> Result<Option<i32>, NulError> { + let key = CString::new(key)?; + let mut value = 0; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call. The value pointer must be valid because it + // comes from a reference. + if unsafe { APersistableBundle_getInt(self.0.as_ptr(), key.as_ptr(), &mut value) } { + Ok(Some(value)) + } else { + Ok(None) + } + } + + /// Gets the i64 value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_long(&self, key: &str) -> Result<Option<i64>, NulError> { + let key = CString::new(key)?; + let mut value = 0; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call. The value pointer must be valid because it + // comes from a reference. + if unsafe { APersistableBundle_getLong(self.0.as_ptr(), key.as_ptr(), &mut value) } { + Ok(Some(value)) + } else { + Ok(None) + } + } + + /// Gets the f64 value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_double(&self, key: &str) -> Result<Option<f64>, NulError> { + let key = CString::new(key)?; + let mut value = 0.0; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call. The value pointer must be valid because it + // comes from a reference. + if unsafe { APersistableBundle_getDouble(self.0.as_ptr(), key.as_ptr(), &mut value) } { + Ok(Some(value)) + } else { + Ok(None) + } + } + + /// Gets the string value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_string(&self, key: &str) -> Result<Option<String>, NulError> { + let key = CString::new(key)?; + let mut value = null_mut(); + let mut allocated_size: usize = 0; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the lifetime of `key`. The value pointer must be valid because it comes + // from a reference. + let value_size_bytes = unsafe { + APersistableBundle_getString( + self.0.as_ptr(), + key.as_ptr(), + &mut value, + Some(string_allocator), + (&raw mut allocated_size).cast(), + ) + }; + match value_size_bytes { + APERSISTABLEBUNDLE_KEY_NOT_FOUND => Ok(None), + APERSISTABLEBUNDLE_ALLOCATOR_FAILED => { + panic!("APersistableBundle_getString failed to allocate string"); + } + _ => { + let raw_slice = slice_from_raw_parts_mut(value.cast(), allocated_size); + // SAFETY: The pointer was returned from string_allocator, which used + // `Box::into_raw`, and we've got the appropriate size back from allocated_size. + let boxed_slice: Box<[u8]> = unsafe { Box::from_raw(raw_slice) }; + assert_eq!( + allocated_size, + usize::try_from(value_size_bytes) + .expect("APersistableBundle_getString returned negative value size") + + 1 + ); + let c_string = CString::from_vec_with_nul(boxed_slice.into()) + .expect("APersistableBundle_getString returned string missing NUL byte"); + let string = c_string + .into_string() + .expect("APersistableBundle_getString returned invalid UTF-8"); + Ok(Some(string)) + } + } + } + + /// Gets the vector of `T` associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + /// + /// `get_func` should be one of the `APersistableBundle_get*Vector` functions from + /// `binder_ndk_sys`. + /// + /// # Safety + /// + /// `get_func` must only require that the pointers it takes are valid for the duration of the + /// call. It must allow a null pointer for the buffer, and must return the size in bytes of + /// buffer it requires. If it is given a non-null buffer pointer it must write that number of + /// bytes to the buffer, which must be a whole number of valid `T` values. + unsafe fn get_vec<T: Clone>( + &self, + key: &str, + default: T, + get_func: unsafe extern "C" fn( + *const APersistableBundle, + *const c_char, + *mut T, + i32, + ) -> i32, + ) -> Result<Option<Vec<T>>, NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the lifetime of `key`. A null pointer is allowed for the buffer. + match unsafe { get_func(self.0.as_ptr(), key.as_ptr(), null_mut(), 0) } { + APERSISTABLEBUNDLE_KEY_NOT_FOUND => Ok(None), + APERSISTABLEBUNDLE_ALLOCATOR_FAILED => { + panic!("APersistableBundle_getStringVector failed to allocate string"); + } + required_buffer_size => { + let mut value = vec![ + default; + usize::try_from(required_buffer_size).expect( + "APersistableBundle_get*Vector returned invalid size" + ) / size_of::<T>() + ]; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for + // the lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` + // is guaranteed to be valid for the lifetime of `key`. The value buffer pointer is + // valid as it comes from the Vec we just allocated. + match unsafe { + get_func( + self.0.as_ptr(), + key.as_ptr(), + value.as_mut_ptr(), + (value.len() * size_of::<T>()).try_into().unwrap(), + ) + } { + APERSISTABLEBUNDLE_KEY_NOT_FOUND => { + panic!("APersistableBundle_get*Vector failed to find key after first finding it"); + } + APERSISTABLEBUNDLE_ALLOCATOR_FAILED => { + panic!("APersistableBundle_getStringVector failed to allocate string"); + } + _ => Ok(Some(value)), + } + } + } + } + + /// Gets the boolean vector value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_bool_vec(&self, key: &str) -> Result<Option<Vec<bool>>, NulError> { + // SAFETY: APersistableBundle_getBooleanVector fulfils all the safety requirements of + // `get_vec`. + unsafe { self.get_vec(key, Default::default(), APersistableBundle_getBooleanVector) } + } + + /// Gets the i32 vector value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_int_vec(&self, key: &str) -> Result<Option<Vec<i32>>, NulError> { + // SAFETY: APersistableBundle_getIntVector fulfils all the safety requirements of + // `get_vec`. + unsafe { self.get_vec(key, Default::default(), APersistableBundle_getIntVector) } + } + + /// Gets the i64 vector value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_long_vec(&self, key: &str) -> Result<Option<Vec<i64>>, NulError> { + // SAFETY: APersistableBundle_getLongVector fulfils all the safety requirements of + // `get_vec`. + unsafe { self.get_vec(key, Default::default(), APersistableBundle_getLongVector) } + } + + /// Gets the f64 vector value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_double_vec(&self, key: &str) -> Result<Option<Vec<f64>>, NulError> { + // SAFETY: APersistableBundle_getDoubleVector fulfils all the safety requirements of + // `get_vec`. + unsafe { self.get_vec(key, Default::default(), APersistableBundle_getDoubleVector) } + } + + /// Gets the string vector value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_string_vec(&self, key: &str) -> Result<Option<Vec<String>>, NulError> { + if let Some(value) = + // SAFETY: `get_string_vector_with_allocator` fulfils all the safety requirements of + // `get_vec`. + unsafe { self.get_vec(key, null_mut(), get_string_vector_with_allocator) }? + { + Ok(Some( + value + .into_iter() + .map(|s| { + // SAFETY: The pointer was returned from `string_allocator`, which used + // `Box::into_raw`, and `APersistableBundle_getStringVector` should have + // written valid bytes to it including a NUL terminator in the last + // position. + let string_length = unsafe { CStr::from_ptr(s) }.count_bytes(); + let raw_slice = slice_from_raw_parts_mut(s.cast(), string_length + 1); + // SAFETY: The pointer was returned from `string_allocator`, which used + // `Box::into_raw`, and we've got the appropriate size back by checking the + // length of the string. + let boxed_slice: Box<[u8]> = unsafe { Box::from_raw(raw_slice) }; + let c_string = CString::from_vec_with_nul(boxed_slice.into()).expect( + "APersistableBundle_getStringVector returned string missing NUL byte", + ); + c_string + .into_string() + .expect("APersistableBundle_getStringVector returned invalid UTF-8") + }) + .collect(), + )) + } else { + Ok(None) + } + } + + /// Gets the `PersistableBundle` value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_persistable_bundle(&self, key: &str) -> Result<Option<Self>, NulError> { + let key = CString::new(key)?; + let mut value = null_mut(); + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the lifetime of `key`. The value pointer must be valid because it comes + // from a reference. + if unsafe { + APersistableBundle_getPersistableBundle(self.0.as_ptr(), key.as_ptr(), &mut value) + } { + Ok(Some(Self(NonNull::new(value).expect( + "APersistableBundle_getPersistableBundle returned true but didn't set outBundle", + )))) + } else { + Ok(None) + } + } + + /// Calls the appropriate `APersistableBundle_get*Keys` function for the given `value_type`, + /// with our `string_allocator` and a null context pointer. + /// + /// # Safety + /// + /// `out_keys` must either be null or point to a buffer of at least `buffer_size_bytes` bytes, + /// properly aligned for `T`, and not otherwise accessed for the duration of the call. + unsafe fn get_keys_raw( + &self, + value_type: ValueType, + out_keys: *mut *mut c_char, + buffer_size_bytes: i32, + ) -> i32 { + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. Our caller guarantees an appropriate value for + // `out_keys` and `buffer_size_bytes`. + unsafe { + match value_type { + ValueType::Boolean => APersistableBundle_getBooleanKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::Integer => APersistableBundle_getIntKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::Long => APersistableBundle_getLongKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::Double => APersistableBundle_getDoubleKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::String => APersistableBundle_getStringKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::BooleanVector => APersistableBundle_getBooleanVectorKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::IntegerVector => APersistableBundle_getIntVectorKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::LongVector => APersistableBundle_getLongVectorKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::DoubleVector => APersistableBundle_getDoubleVectorKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::StringVector => APersistableBundle_getStringVectorKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + ValueType::PersistableBundle => APersistableBundle_getPersistableBundleKeys( + self.0.as_ptr(), + out_keys, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ), + } + } + } + + /// Gets all the keys associated with values of the given type. + pub fn keys_for_type(&self, value_type: ValueType) -> Vec<String> { + // SAFETY: A null pointer is allowed for the buffer. + match unsafe { self.get_keys_raw(value_type, null_mut(), 0) } { + APERSISTABLEBUNDLE_ALLOCATOR_FAILED => { + panic!("APersistableBundle_get*Keys failed to allocate string"); + } + required_buffer_size => { + let required_buffer_size_usize = usize::try_from(required_buffer_size) + .expect("APersistableBundle_get*Keys returned invalid size"); + assert_eq!(required_buffer_size_usize % size_of::<*mut c_char>(), 0); + let mut keys = + vec![null_mut(); required_buffer_size_usize / size_of::<*mut c_char>()]; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for + // the lifetime of the `PersistableBundle`. The keys buffer pointer is valid as it + // comes from the Vec we just allocated. + if unsafe { self.get_keys_raw(value_type, keys.as_mut_ptr(), required_buffer_size) } + == APERSISTABLEBUNDLE_ALLOCATOR_FAILED + { + panic!("APersistableBundle_get*Keys failed to allocate string"); + } + keys.into_iter() + .map(|key| { + // SAFETY: The pointer was returned from `string_allocator`, which used + // `Box::into_raw`, and `APersistableBundle_getStringVector` should have + // written valid bytes to it including a NUL terminator in the last + // position. + let string_length = unsafe { CStr::from_ptr(key) }.count_bytes(); + let raw_slice = slice_from_raw_parts_mut(key.cast(), string_length + 1); + // SAFETY: The pointer was returned from `string_allocator`, which used + // `Box::into_raw`, and we've got the appropriate size back by checking the + // length of the string. + let boxed_slice: Box<[u8]> = unsafe { Box::from_raw(raw_slice) }; + let c_string = CString::from_vec_with_nul(boxed_slice.into()) + .expect("APersistableBundle_get*Keys returned string missing NUL byte"); + c_string + .into_string() + .expect("APersistableBundle_get*Keys returned invalid UTF-8") + }) + .collect() + } + } + } + + /// Returns an iterator over all keys in the bundle, along with the type of their associated + /// value. + pub fn keys(&self) -> impl Iterator<Item = (String, ValueType)> + use<'_> { + [ + ValueType::Boolean, + ValueType::Integer, + ValueType::Long, + ValueType::Double, + ValueType::String, + ValueType::BooleanVector, + ValueType::IntegerVector, + ValueType::LongVector, + ValueType::DoubleVector, + ValueType::StringVector, + ValueType::PersistableBundle, + ] + .iter() + .flat_map(|value_type| { + self.keys_for_type(*value_type).into_iter().map(|key| (key, *value_type)) + }) + } +} + +/// Wrapper around `APersistableBundle_getStringVector` to pass `string_allocator` and a null +/// context pointer. +/// +/// # Safety +/// +/// * `bundle` must point to a valid `APersistableBundle` which is not modified for the duration of +/// the call. +/// * `key` must point to a valid NUL-terminated C string. +/// * `buffer` must either be null or point to a buffer of at least `buffer_size_bytes` bytes, +/// properly aligned for `T`, and not otherwise accessed for the duration of the call. +unsafe extern "C" fn get_string_vector_with_allocator( + bundle: *const APersistableBundle, + key: *const c_char, + buffer: *mut *mut c_char, + buffer_size_bytes: i32, +) -> i32 { + // SAFETY: The safety requirements are all guaranteed by our caller according to the safety + // documentation above. + unsafe { + APersistableBundle_getStringVector( + bundle, + key, + buffer, + buffer_size_bytes, + Some(string_allocator), + null_mut(), + ) + } +} + +// SAFETY: The underlying *APersistableBundle can be moved between threads. +unsafe impl Send for PersistableBundle {} + +// SAFETY: The underlying *APersistableBundle can be read from multiple threads, and we require +// `&mut PersistableBundle` for any operations which mutate it. +unsafe impl Sync for PersistableBundle {} + +impl Default for PersistableBundle { + fn default() -> Self { + Self::new() + } +} + +impl Drop for PersistableBundle { + fn drop(&mut self) { + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of this `PersistableBundle`. + unsafe { APersistableBundle_delete(self.0.as_ptr()) }; + } +} + +impl Clone for PersistableBundle { + fn clone(&self) -> Self { + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. + let duplicate = unsafe { APersistableBundle_dup(self.0.as_ptr()) }; + Self(NonNull::new(duplicate).expect("Duplicated APersistableBundle was null")) + } +} + +impl PartialEq for PersistableBundle { + fn eq(&self, other: &Self) -> bool { + // SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the + // lifetime of the `PersistableBundle`s. + unsafe { APersistableBundle_isEqual(self.0.as_ptr(), other.0.as_ptr()) } + } +} + +impl UnstructuredParcelable for PersistableBundle { + fn write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> { + let status = + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. `parcel.as_native_mut()` always returns a valid + // parcel pointer. + unsafe { APersistableBundle_writeToParcel(self.0.as_ptr(), parcel.as_native_mut()) }; + status_result(status) + } + + fn from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode> { + let mut bundle = null_mut(); + + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. `parcel.as_native()` always returns a valid parcel + // pointer. + let status = unsafe { APersistableBundle_readFromParcel(parcel.as_native(), &mut bundle) }; + status_result(status)?; + + Ok(Self(NonNull::new(bundle).expect( + "APersistableBundle_readFromParcel returned success but didn't allocate bundle", + ))) + } +} + +/// Allocates a boxed slice of the given size in bytes, returns a pointer to it and writes its size +/// to `*context`. +/// +/// # Safety +/// +/// `context` must either be null or point to a `usize` to which we can write. +unsafe extern "C" fn string_allocator(size: i32, context: *mut c_void) -> *mut c_char { + let Ok(size) = size.try_into() else { + return null_mut(); + }; + let Ok(boxed_slice) = <[c_char]>::new_box_zeroed_with_elems(size) else { + return null_mut(); + }; + if !context.is_null() { + // SAFETY: The caller promised that `context` is either null or points to a `usize` to which + // we can write, and we just checked that it's not null. + unsafe { + *context.cast::<usize>() = size; + } + } + Box::into_raw(boxed_slice).cast() +} + +impl_deserialize_for_unstructured_parcelable!(PersistableBundle); +impl_serialize_for_unstructured_parcelable!(PersistableBundle); + +/// The types which may be stored as values in a [`PersistableBundle`]. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum ValueType { + /// A `bool`. + Boolean, + /// An `i32`. + Integer, + /// An `i64`. + Long, + /// An `f64`. + Double, + /// A string. + String, + /// A vector of `bool`s. + BooleanVector, + /// A vector of `i32`s. + IntegerVector, + /// A vector of `i64`s. + LongVector, + /// A vector of `f64`s. + DoubleVector, + /// A vector of strings. + StringVector, + /// A nested `PersistableBundle`. + PersistableBundle, +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn create_delete() { + let bundle = PersistableBundle::new(); + drop(bundle); + } + + #[test] + fn duplicate_equal() { + let bundle = PersistableBundle::new(); + let duplicate = bundle.clone(); + assert_eq!(bundle, duplicate); + } + + #[test] + fn get_empty() { + let bundle = PersistableBundle::new(); + assert_eq!(bundle.get_bool("foo"), Ok(None)); + assert_eq!(bundle.get_int("foo"), Ok(None)); + assert_eq!(bundle.get_long("foo"), Ok(None)); + assert_eq!(bundle.get_double("foo"), Ok(None)); + assert_eq!(bundle.get_bool_vec("foo"), Ok(None)); + assert_eq!(bundle.get_int_vec("foo"), Ok(None)); + assert_eq!(bundle.get_long_vec("foo"), Ok(None)); + assert_eq!(bundle.get_double_vec("foo"), Ok(None)); + assert_eq!(bundle.get_string("foo"), Ok(None)); + } + + #[test] + fn remove_empty() { + let mut bundle = PersistableBundle::new(); + assert_eq!(bundle.remove("foo"), Ok(false)); + } + + #[test] + fn insert_get_primitives() { + let mut bundle = PersistableBundle::new(); + + assert_eq!(bundle.insert_bool("bool", true), Ok(())); + assert_eq!(bundle.insert_int("int", 42), Ok(())); + assert_eq!(bundle.insert_long("long", 66), Ok(())); + assert_eq!(bundle.insert_double("double", 123.4), Ok(())); + + assert_eq!(bundle.get_bool("bool"), Ok(Some(true))); + assert_eq!(bundle.get_int("int"), Ok(Some(42))); + assert_eq!(bundle.get_long("long"), Ok(Some(66))); + assert_eq!(bundle.get_double("double"), Ok(Some(123.4))); + assert_eq!(bundle.size(), 4); + + // Getting the wrong type should return nothing. + assert_eq!(bundle.get_int("bool"), Ok(None)); + assert_eq!(bundle.get_long("bool"), Ok(None)); + assert_eq!(bundle.get_double("bool"), Ok(None)); + assert_eq!(bundle.get_bool("int"), Ok(None)); + assert_eq!(bundle.get_long("int"), Ok(None)); + assert_eq!(bundle.get_double("int"), Ok(None)); + assert_eq!(bundle.get_bool("long"), Ok(None)); + assert_eq!(bundle.get_int("long"), Ok(None)); + assert_eq!(bundle.get_double("long"), Ok(None)); + assert_eq!(bundle.get_bool("double"), Ok(None)); + assert_eq!(bundle.get_int("double"), Ok(None)); + assert_eq!(bundle.get_long("double"), Ok(None)); + + // If they are removed they should no longer be present. + assert_eq!(bundle.remove("bool"), Ok(true)); + assert_eq!(bundle.remove("int"), Ok(true)); + assert_eq!(bundle.remove("long"), Ok(true)); + assert_eq!(bundle.remove("double"), Ok(true)); + assert_eq!(bundle.get_bool("bool"), Ok(None)); + assert_eq!(bundle.get_int("int"), Ok(None)); + assert_eq!(bundle.get_long("long"), Ok(None)); + assert_eq!(bundle.get_double("double"), Ok(None)); + assert_eq!(bundle.size(), 0); + } + + #[test] + fn insert_get_string() { + let mut bundle = PersistableBundle::new(); + + assert_eq!(bundle.insert_string("string", "foo"), Ok(())); + assert_eq!(bundle.insert_string("empty", ""), Ok(())); + assert_eq!(bundle.size(), 2); + + assert_eq!(bundle.get_string("string"), Ok(Some("foo".to_string()))); + assert_eq!(bundle.get_string("empty"), Ok(Some("".to_string()))); + } + + #[test] + fn insert_get_vec() { + let mut bundle = PersistableBundle::new(); + + assert_eq!(bundle.insert_bool_vec("bool", &[]), Ok(())); + assert_eq!(bundle.insert_int_vec("int", &[42]), Ok(())); + assert_eq!(bundle.insert_long_vec("long", &[66, 67, 68]), Ok(())); + assert_eq!(bundle.insert_double_vec("double", &[123.4]), Ok(())); + assert_eq!(bundle.insert_string_vec("string", &["foo", "bar", "baz"]), Ok(())); + assert_eq!( + bundle.insert_string_vec( + "string", + &[&"foo".to_string(), &"bar".to_string(), &"baz".to_string()] + ), + Ok(()) + ); + assert_eq!( + bundle.insert_string_vec( + "string", + &["foo".to_string(), "bar".to_string(), "baz".to_string()] + ), + Ok(()) + ); + + assert_eq!(bundle.size(), 5); + + assert_eq!(bundle.get_bool_vec("bool"), Ok(Some(vec![]))); + assert_eq!(bundle.get_int_vec("int"), Ok(Some(vec![42]))); + assert_eq!(bundle.get_long_vec("long"), Ok(Some(vec![66, 67, 68]))); + assert_eq!(bundle.get_double_vec("double"), Ok(Some(vec![123.4]))); + assert_eq!( + bundle.get_string_vec("string"), + Ok(Some(vec!["foo".to_string(), "bar".to_string(), "baz".to_string()])) + ); + } + + #[test] + fn insert_get_bundle() { + let mut bundle = PersistableBundle::new(); + + let mut sub_bundle = PersistableBundle::new(); + assert_eq!(sub_bundle.insert_int("int", 42), Ok(())); + assert_eq!(sub_bundle.size(), 1); + assert_eq!(bundle.insert_persistable_bundle("bundle", &sub_bundle), Ok(())); + + assert_eq!(bundle.get_persistable_bundle("bundle"), Ok(Some(sub_bundle))); + } + + #[test] + fn get_keys() { + let mut bundle = PersistableBundle::new(); + + assert_eq!(bundle.keys_for_type(ValueType::Boolean), Vec::<String>::new()); + assert_eq!(bundle.keys_for_type(ValueType::Integer), Vec::<String>::new()); + assert_eq!(bundle.keys_for_type(ValueType::StringVector), Vec::<String>::new()); + + assert_eq!(bundle.insert_bool("bool1", false), Ok(())); + assert_eq!(bundle.insert_bool("bool2", true), Ok(())); + assert_eq!(bundle.insert_int("int", 42), Ok(())); + + assert_eq!( + bundle.keys_for_type(ValueType::Boolean), + vec!["bool1".to_string(), "bool2".to_string()] + ); + assert_eq!(bundle.keys_for_type(ValueType::Integer), vec!["int".to_string()]); + assert_eq!(bundle.keys_for_type(ValueType::StringVector), Vec::<String>::new()); + + assert_eq!( + bundle.keys().collect::<Vec<_>>(), + vec![ + ("bool1".to_string(), ValueType::Boolean), + ("bool2".to_string(), ValueType::Boolean), + ("int".to_string(), ValueType::Integer), + ] + ); + } +} diff --git a/libs/binder/rust/src/state.rs b/libs/binder/rust/src/state.rs index c0cac830d7..609334eb53 100644 --- a/libs/binder/rust/src/state.rs +++ b/libs/binder/rust/src/state.rs @@ -28,8 +28,9 @@ impl ProcessState { /// `num_threads` additional threads as specified by /// [`set_thread_pool_max_thread_count`](Self::set_thread_pool_max_thread_count). /// - /// This should be done before creating any Binder client or server. If - /// neither this nor [`join_thread_pool`](Self::join_thread_pool) are + /// If this is called, it must be done before creating any Binder client or server. + /// + /// If neither this nor [`join_thread_pool`](Self::join_thread_pool) are /// called, then some things (such as callbacks and /// [`IBinder::link_to_death`](crate::IBinder::link_to_death)) will silently /// not work: the callbacks will be queued but never called as there is no diff --git a/libs/binder/rust/sys/BinderBindings.hpp b/libs/binder/rust/sys/BinderBindings.hpp index 557f0e895d..c19e375a97 100644 --- a/libs/binder/rust/sys/BinderBindings.hpp +++ b/libs/binder/rust/sys/BinderBindings.hpp @@ -17,6 +17,7 @@ #include <android/binder_ibinder.h> #include <android/binder_parcel.h> #include <android/binder_status.h> +#include <android/persistable_bundle.h> /* Platform only */ #if defined(ANDROID_PLATFORM) || defined(__ANDROID_VENDOR__) @@ -91,6 +92,11 @@ enum { #endif }; +enum { + APERSISTABLEBUNDLE_KEY_NOT_FOUND = APERSISTABLEBUNDLE_KEY_NOT_FOUND, + APERSISTABLEBUNDLE_ALLOCATOR_FAILED = APERSISTABLEBUNDLE_ALLOCATOR_FAILED, +}; + } // namespace consts } // namespace c_interface diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp index be990657d5..78fe2a8714 100644 --- a/libs/binder/servicedispatcher.cpp +++ b/libs/binder/servicedispatcher.cpp @@ -127,7 +127,12 @@ public: // We can't send BpBinder for regular binder over RPC. return android::binder::Status::fromStatusT(android::INVALID_OPERATION); } - android::binder::Status checkService(const std::string&, android::os::Service*) override { + android::binder::Status checkService(const std::string&, + android::sp<android::IBinder>*) override { + // We can't send BpBinder for regular binder over RPC. + return android::binder::Status::fromStatusT(android::INVALID_OPERATION); + } + android::binder::Status checkService2(const std::string&, android::os::Service*) override { // We can't send BpBinder for regular binder over RPC. return android::binder::Status::fromStatusT(android::INVALID_OPERATION); } diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp index c21d7c61cd..f412dfb6f4 100644 --- a/libs/binder/tests/Android.bp +++ b/libs/binder/tests/Android.bp @@ -803,6 +803,28 @@ cc_test { } cc_test { + name: "binderStabilityIntegrationTest", + defaults: ["binder_test_defaults"], + srcs: [ + "binderStabilityIntegrationTest.cpp", + ], + + shared_libs: [ + "libbinder", + "libutils", + ], + static_libs: [ + "libprocpartition", + ], + + test_suites: [ + "general-tests", + "vts", + ], + require_root: true, +} + +cc_test { name: "binderAllocationLimits", defaults: ["binder_test_defaults"], srcs: ["binderAllocationLimits.cpp"], diff --git a/libs/binder/tests/IBinderRpcTest.aidl b/libs/binder/tests/IBinderRpcTest.aidl index 116476765a..dcd6461b53 100644 --- a/libs/binder/tests/IBinderRpcTest.aidl +++ b/libs/binder/tests/IBinderRpcTest.aidl @@ -34,6 +34,8 @@ interface IBinderRpcTest { void holdBinder(@nullable IBinder binder); @nullable IBinder getHeldBinder(); + byte[] repeatBytes(in byte[] bytes); + // Idea is client creates its own instance of IBinderRpcTest and calls this, // and the server calls 'binder' with (calls - 1) passing itself as 'binder', // going back and forth until calls = 0 diff --git a/libs/binder/tests/binderAllocationLimits.cpp b/libs/binder/tests/binderAllocationLimits.cpp index c0c0aae80b..339ce4bdf8 100644 --- a/libs/binder/tests/binderAllocationLimits.cpp +++ b/libs/binder/tests/binderAllocationLimits.cpp @@ -22,17 +22,33 @@ #include <binder/RpcServer.h> #include <binder/RpcSession.h> #include <cutils/trace.h> +#include <gtest/gtest-spi.h> #include <gtest/gtest.h> #include <utils/CallStack.h> #include <malloc.h> +#include <atomic> #include <functional> +#include <numeric> #include <vector> using namespace android::binder::impl; static android::String8 gEmpty(""); // make sure first allocation from optimization runs +struct State { + State(std::vector<size_t>&& expectedMallocs) : expectedMallocs(std::move(expectedMallocs)) {} + ~State() { + size_t num = numMallocs.load(); + if (expectedMallocs.size() != num) { + ADD_FAILURE() << "Expected " << expectedMallocs.size() << " allocations, but got " + << num; + } + } + const std::vector<size_t> expectedMallocs; + std::atomic<size_t> numMallocs; +}; + struct DestructionAction { DestructionAction(std::function<void()> f) : mF(std::move(f)) {} ~DestructionAction() { mF(); }; @@ -95,8 +111,7 @@ namespace LambdaHooks { // Action to execute when malloc is hit. Supports nesting. Malloc is not // restricted when the allocation hook is being processed. -__attribute__((warn_unused_result)) -DestructionAction OnMalloc(LambdaHooks::AllocationHook f) { +__attribute__((warn_unused_result)) DestructionAction OnMalloc(LambdaHooks::AllocationHook f) { MallocHooks before = MallocHooks::save(); LambdaHooks::lambdas.emplace_back(std::move(f)); LambdaHooks::lambda_malloc_hooks.overwrite(); @@ -106,6 +121,22 @@ DestructionAction OnMalloc(LambdaHooks::AllocationHook f) { }); } +DestructionAction setExpectedMallocs(std::vector<size_t>&& expected) { + auto state = std::make_shared<State>(std::move(expected)); + return OnMalloc([state = state](size_t bytes) { + size_t num = state->numMallocs.fetch_add(1); + if (num >= state->expectedMallocs.size() || state->expectedMallocs[num] != bytes) { + ADD_FAILURE() << "Unexpected allocation number " << num << " of size " << bytes + << " bytes" << std::endl + << android::CallStack::stackToString("UNEXPECTED ALLOCATION", + android::CallStack::getCurrent( + 4 /*ignoreDepth*/) + .get()) + << std::endl; + } + }); +} + // exported symbol, to force compiler not to optimize away pointers we set here const void* imaginary_use; @@ -119,16 +150,53 @@ TEST(TestTheTest, OnMalloc) { imaginary_use = new int[10]; } + delete[] reinterpret_cast<const int*>(imaginary_use); EXPECT_EQ(mallocs, 1u); } +TEST(TestTheTest, OnMallocWithExpectedMallocs) { + std::vector<size_t> expectedMallocs = { + 4, + 16, + 8, + }; + { + const auto on_malloc = setExpectedMallocs(std::move(expectedMallocs)); + imaginary_use = new int32_t[1]; + delete[] reinterpret_cast<const int*>(imaginary_use); + imaginary_use = new int32_t[4]; + delete[] reinterpret_cast<const int*>(imaginary_use); + imaginary_use = new int32_t[2]; + delete[] reinterpret_cast<const int*>(imaginary_use); + } +} + +TEST(TestTheTest, OnMallocWithExpectedMallocsWrongSize) { + std::vector<size_t> expectedMallocs = { + 4, + 16, + 100000, + }; + EXPECT_NONFATAL_FAILURE( + { + const auto on_malloc = setExpectedMallocs(std::move(expectedMallocs)); + imaginary_use = new int32_t[1]; + delete[] reinterpret_cast<const int*>(imaginary_use); + imaginary_use = new int32_t[4]; + delete[] reinterpret_cast<const int*>(imaginary_use); + imaginary_use = new int32_t[2]; + delete[] reinterpret_cast<const int*>(imaginary_use); + }, + "Unexpected allocation number 2 of size 8 bytes"); +} __attribute__((warn_unused_result)) DestructionAction ScopeDisallowMalloc() { return OnMalloc([&](size_t bytes) { - ADD_FAILURE() << "Unexpected allocation: " << bytes; + FAIL() << "Unexpected allocation: " << bytes; using android::CallStack; - std::cout << CallStack::stackToString("UNEXPECTED ALLOCATION", CallStack::getCurrent(4 /*ignoreDepth*/).get()) + std::cout << CallStack::stackToString("UNEXPECTED ALLOCATION", + CallStack::getCurrent(4 /*ignoreDepth*/).get()) << std::endl; }); } @@ -224,6 +292,51 @@ TEST(BinderAllocation, SmallTransaction) { EXPECT_EQ(mallocs, 1u); } +TEST(BinderAccessorAllocation, AddAccessorCheckService) { + // Need to call defaultServiceManager() before checking malloc because it + // will allocate an instance in the call_once + const auto sm = defaultServiceManager(); + const std::string kInstanceName1 = "foo.bar.IFoo/default"; + const std::string kInstanceName2 = "foo.bar.IFoo2/default"; + const String16 kInstanceName16(kInstanceName1.c_str()); + std::vector<size_t> expectedMallocs = { + // addAccessorProvider + 112, // new AccessorProvider + 16, // new AccessorProviderEntry + // checkService + 45, // String8 from String16 in CppShim::checkService + 128, // writeInterfaceToken + 16, // getInjectedAccessor, new AccessorProviderEntry + 66, // getInjectedAccessor, String16 + 45, // String8 from String16 in AccessorProvider::provide + }; + std::set<std::string> supportedInstances = {kInstanceName1, kInstanceName2}; + auto onMalloc = setExpectedMallocs(std::move(expectedMallocs)); + + auto receipt = + android::addAccessorProvider(std::move(supportedInstances), + [&](const String16&) -> sp<IBinder> { return nullptr; }); + EXPECT_FALSE(receipt.expired()); + + sp<IBinder> binder = sm->checkService(kInstanceName16); + + status_t status = android::removeAccessorProvider(receipt); +} + +TEST(BinderAccessorAllocation, AddAccessorEmpty) { + std::vector<size_t> expectedMallocs = { + 48, // From ALOGE with empty set of instances + }; + std::set<std::string> supportedInstances = {}; + auto onMalloc = setExpectedMallocs(std::move(expectedMallocs)); + + auto receipt = + android::addAccessorProvider(std::move(supportedInstances), + [&](const String16&) -> sp<IBinder> { return nullptr; }); + + EXPECT_TRUE(receipt.expired()); +} + TEST(RpcBinderAllocation, SetupRpcServer) { std::string tmp = getenv("TMPDIR") ?: "/tmp"; std::string addr = tmp + "/binderRpcBenchmark"; @@ -255,6 +368,7 @@ TEST(RpcBinderAllocation, SetupRpcServer) { } int main(int argc, char** argv) { + LOG(INFO) << "Priming static log variables for binderAllocationLimits."; if (getenv("LIBC_HOOKS_ENABLE") == nullptr) { CHECK(0 == setenv("LIBC_HOOKS_ENABLE", "1", true /*overwrite*/)); execv(argv[0], argv); diff --git a/libs/binder/tests/binderCacheUnitTest.cpp b/libs/binder/tests/binderCacheUnitTest.cpp index 19395c2dcd..121e5ae5e9 100644 --- a/libs/binder/tests/binderCacheUnitTest.cpp +++ b/libs/binder/tests/binderCacheUnitTest.cpp @@ -74,7 +74,7 @@ class MockAidlServiceManager : public os::IServiceManagerDefault { public: MockAidlServiceManager() : innerSm() {} - binder::Status checkService(const ::std::string& name, os::Service* _out) override { + binder::Status checkService2(const ::std::string& name, os::Service* _out) override { os::ServiceWithMetadata serviceWithMetadata = os::ServiceWithMetadata(); serviceWithMetadata.service = innerSm.getService(String16(name.c_str())); serviceWithMetadata.isLazyService = false; @@ -98,7 +98,7 @@ class MockAidlServiceManager2 : public os::IServiceManagerDefault { public: MockAidlServiceManager2() : innerSm() {} - binder::Status checkService(const ::std::string& name, os::Service* _out) override { + binder::Status checkService2(const ::std::string& name, os::Service* _out) override { os::ServiceWithMetadata serviceWithMetadata = os::ServiceWithMetadata(); serviceWithMetadata.service = innerSm.getService(String16(name.c_str())); serviceWithMetadata.isLazyService = true; diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp index 9f656ec96c..170b2adfbb 100644 --- a/libs/binder/tests/binderRpcTest.cpp +++ b/libs/binder/tests/binderRpcTest.cpp @@ -711,6 +711,35 @@ TEST_P(BinderRpc, OnewayCallExhaustion) { proc.proc->sessions.erase(proc.proc->sessions.begin() + 1); } +// TODO(b/392717039): can we move this to universal tests? +TEST_P(BinderRpc, SendTooLargeVector) { + if (GetParam().singleThreaded) { + GTEST_SKIP() << "Requires multi-threaded server to test one of the sessions crashing."; + } + + auto proc = createRpcTestSocketServerProcess({.numSessions = 2}); + + // need a working transaction + EXPECT_EQ(OK, proc.rootBinder->pingBinder()); + + // see libbinder internal Constants.h + const size_t kTooLargeSize = 650 * 1024; + const std::vector<uint8_t> kTestValue(kTooLargeSize / sizeof(uint8_t), 42); + + // TODO(b/392717039): Telling a server to allocate too much data currently causes the session to + // close since RpcServer treats any transaction error as a failure. We likely want to change + // this behavior to be a soft failure, since it isn't hard to keep track of this state. + sp<IBinderRpcTest> rootIface2 = interface_cast<IBinderRpcTest>(proc.proc->sessions.at(1).root); + std::vector<uint8_t> result; + status_t res = rootIface2->repeatBytes(kTestValue, &result).transactionError(); + + // TODO(b/392717039): consistent error results always + EXPECT_TRUE(res == -ECONNRESET || res == DEAD_OBJECT) << statusToString(res); + + // died, so remove it for checks in destructor of proc + proc.proc->sessions.erase(proc.proc->sessions.begin() + 1); +} + TEST_P(BinderRpc, SessionWithIncomingThreadpoolDoesntLeak) { if (clientOrServerSingleThreaded()) { GTEST_SKIP() << "This test requires multiple threads"; @@ -2742,7 +2771,9 @@ INSTANTIATE_TEST_SUITE_P( int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); +#ifndef __ANDROID__ __android_log_set_logger(__android_log_stderr_logger); +#endif return RUN_ALL_TESTS(); } diff --git a/libs/binder/tests/binderRpcTestCommon.h b/libs/binder/tests/binderRpcTestCommon.h index dc22647b85..6e0024628a 100644 --- a/libs/binder/tests/binderRpcTestCommon.h +++ b/libs/binder/tests/binderRpcTestCommon.h @@ -348,6 +348,10 @@ public: *out = binder; return Status::ok(); } + Status repeatBytes(const std::vector<uint8_t>& bytes, std::vector<uint8_t>* out) override { + *out = bytes; + return Status::ok(); + } static sp<IBinder> mHeldBinder; Status holdBinder(const sp<IBinder>& binder) override { mHeldBinder = binder; diff --git a/libs/binder/tests/binderRpcTestService.cpp b/libs/binder/tests/binderRpcTestService.cpp index aef946481f..0084b9ada2 100644 --- a/libs/binder/tests/binderRpcTestService.cpp +++ b/libs/binder/tests/binderRpcTestService.cpp @@ -100,7 +100,9 @@ public: }; int main(int argc, char* argv[]) { +#ifndef __ANDROID__ __android_log_set_logger(__android_log_stderr_logger); +#endif LOG_ALWAYS_FATAL_IF(argc != 3, "Invalid number of arguments: %d", argc); unique_fd writeEnd(atoi(argv[1])); diff --git a/libs/binder/tests/binderRpcUniversalTests.cpp b/libs/binder/tests/binderRpcUniversalTests.cpp index c6fd4870a0..d227e6eeec 100644 --- a/libs/binder/tests/binderRpcUniversalTests.cpp +++ b/libs/binder/tests/binderRpcUniversalTests.cpp @@ -209,6 +209,18 @@ TEST_P(BinderRpc, RepeatBinder) { EXPECT_EQ(0, MyBinderRpcSession::gNum); } +TEST_P(BinderRpc, SendLargeVector) { + auto proc = createRpcTestSocketServerProcess({}); + + // see libbinder internal Constants.h + const size_t kLargeSize = 550 * 1024; + const std::vector<uint8_t> kTestValue(kLargeSize / sizeof(uint8_t), 42); + + std::vector<uint8_t> result; + EXPECT_OK(proc.rootIface->repeatBytes(kTestValue, &result)); + EXPECT_EQ(result, kTestValue); +} + TEST_P(BinderRpc, RepeatTheirBinder) { auto proc = createRpcTestSocketServerProcess({}); @@ -498,9 +510,9 @@ TEST_P(BinderRpc, Callbacks) { // same thread, everything should have happened in a nested call. Otherwise, // the callback will be processed on another thread. if (callIsOneway || callbackIsOneway || delayed) { - using std::literals::chrono_literals::operator""s; + using std::literals::chrono_literals::operator""ms; RpcMutexUniqueLock _l(cb->mMutex); - cb->mCv.wait_for(_l, 1s, [&] { return !cb->mValues.empty(); }); + cb->mCv.wait_for(_l, 1500ms, [&] { return !cb->mValues.empty(); }); } EXPECT_EQ(cb->mValues.size(), 1UL) diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp index 7d1556e7d2..45b2103637 100644 --- a/libs/binder/tests/binderSafeInterfaceTest.cpp +++ b/libs/binder/tests/binderSafeInterfaceTest.cpp @@ -858,7 +858,13 @@ TEST_F(SafeInterfaceTest, TestIncrementTwo) { ASSERT_EQ(b + 1, bPlusOne); } -extern "C" int main(int argc, char **argv) { +} // namespace tests +} // namespace android + +int main(int argc, char** argv) { + using namespace android; + using namespace android::tests; + testing::InitGoogleTest(&argc, argv); if (fork() == 0) { @@ -875,6 +881,3 @@ extern "C" int main(int argc, char **argv) { return RUN_ALL_TESTS(); } - -} // namespace tests -} // namespace android diff --git a/libs/binder/tests/binderStabilityIntegrationTest.cpp b/libs/binder/tests/binderStabilityIntegrationTest.cpp new file mode 100644 index 0000000000..cbc4180480 --- /dev/null +++ b/libs/binder/tests/binderStabilityIntegrationTest.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <binder/Binder.h> +#include <binder/IServiceManager.h> +#include <binder/Stability.h> +#include <gtest/gtest.h> +#include <procpartition/procpartition.h> + +using namespace android; +using android::internal::Stability; // for testing only! +using android::procpartition::getPartition; +using android::procpartition::Partition; + +class BinderStabilityIntegrationTest : public testing::Test, + public ::testing::WithParamInterface<String16> { +public: + virtual ~BinderStabilityIntegrationTest() {} +}; + +TEST_P(BinderStabilityIntegrationTest, ExpectedStabilityForItsPartition) { + const String16& serviceName = GetParam(); + + sp<IBinder> binder = defaultServiceManager()->checkService(serviceName); + if (!binder) GTEST_SKIP() << "Could not get service, may have gone away."; + + pid_t pid; + status_t res = binder->getDebugPid(&pid); + if (res != OK) { + GTEST_SKIP() << "Could not talk to service to get PID, res: " << statusToString(res); + } + + Partition partition = getPartition(pid); + + Stability::Level level = Stability::Level::UNDECLARED; + switch (partition) { + case Partition::PRODUCT: + case Partition::SYSTEM: + case Partition::SYSTEM_EXT: + level = Stability::Level::SYSTEM; + break; + case Partition::VENDOR: + case Partition::ODM: + level = Stability::Level::VENDOR; + break; + case Partition::UNKNOWN: + GTEST_SKIP() << "Not sure of partition of process."; + return; + default: + ADD_FAILURE() << "Unrecognized partition for service: " << partition; + return; + } + + ASSERT_TRUE(Stability::check(Stability::getRepr(binder.get()), level)) + << "Binder hosted on partition " << partition + << " should have corresponding stability set."; +} + +std::string PrintTestParam( + const testing::TestParamInfo<BinderStabilityIntegrationTest::ParamType>& info) { + std::string name = String8(info.param).c_str(); + for (size_t i = 0; i < name.size(); i++) { + bool alnum = false; + alnum |= (name[i] >= 'a' && name[i] <= 'z'); + alnum |= (name[i] >= 'A' && name[i] <= 'Z'); + alnum |= (name[i] >= '0' && name[i] <= '9'); + alnum |= (name[i] == '_'); + if (!alnum) name[i] = '_'; + } + + // index for uniqueness + return std::to_string(info.index) + "__" + name; +} + +INSTANTIATE_TEST_CASE_P(RegisteredServices, BinderStabilityIntegrationTest, + ::testing::ValuesIn(defaultServiceManager()->listServices()), + PrintTestParam); diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp index cac054eb1b..457eaa5a76 100644 --- a/libs/binder/tests/parcel_fuzzer/Android.bp +++ b/libs/binder/tests/parcel_fuzzer/Android.bp @@ -109,6 +109,9 @@ cc_library_static { "libcutils", "libutils", ], + header_libs: [ + "libaidl_transactions", + ], local_include_dirs: ["include_random_parcel"], export_include_dirs: ["include_random_parcel"], } diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp index 401c2749ef..b2ba1ae38d 100644 --- a/libs/binder/tests/parcel_fuzzer/binder.cpp +++ b/libs/binder/tests/parcel_fuzzer/binder.cpp @@ -317,8 +317,6 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS { PARCEL_READ_NO_STATUS(int, readParcelFileDescriptor), PARCEL_READ_WITH_STATUS(unique_fd, readUniqueFileDescriptor), - PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<unique_fd>>, - readUniqueFileDescriptorVector), PARCEL_READ_WITH_STATUS(std::optional<std::vector<unique_fd>>, readUniqueFileDescriptorVector), PARCEL_READ_WITH_STATUS(std::vector<unique_fd>, readUniqueFileDescriptorVector), diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp index 02e69cc371..11aa76891b 100644 --- a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp +++ b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include <aidl/transaction_ids.h> #include <fuzzbinder/libbinder_driver.h> #include <fuzzbinder/random_parcel.h> @@ -31,6 +33,28 @@ void fuzzService(const sp<IBinder>& binder, FuzzedDataProvider&& provider) { fuzzService(std::vector<sp<IBinder>>{binder}, std::move(provider)); } +uint32_t getCode(FuzzedDataProvider& provider) { + if (provider.ConsumeBool()) { + return provider.ConsumeIntegral<uint32_t>(); + } + + // Most of the AIDL services will have small set of transaction codes. + if (provider.ConsumeBool()) { + return provider.ConsumeIntegralInRange<uint32_t>(0, 100); + } + + if (provider.ConsumeBool()) { + return provider.PickValueInArray<uint32_t>( + {IBinder::DUMP_TRANSACTION, IBinder::PING_TRANSACTION, + IBinder::SHELL_COMMAND_TRANSACTION, IBinder::INTERFACE_TRANSACTION, + IBinder::SYSPROPS_TRANSACTION, IBinder::EXTENSION_TRANSACTION, + IBinder::TWEET_TRANSACTION, IBinder::LIKE_TRANSACTION}); + } + + return provider.ConsumeIntegralInRange<uint32_t>(aidl::kLastMetaMethodId, + aidl::kFirstMetaMethodId); +} + void fuzzService(const std::vector<sp<IBinder>>& binders, FuzzedDataProvider&& provider) { RandomParcelOptions options{ .extraBinders = binders, @@ -61,16 +85,7 @@ void fuzzService(const std::vector<sp<IBinder>>& binders, FuzzedDataProvider&& p } while (provider.remaining_bytes() > 0) { - // Most of the AIDL services will have small set of transaction codes. - // TODO(b/295942369) : Add remaining transact codes from IBinder.h - uint32_t code = provider.ConsumeBool() ? provider.ConsumeIntegral<uint32_t>() - : provider.ConsumeBool() - ? provider.ConsumeIntegralInRange<uint32_t>(0, 100) - : provider.PickValueInArray<uint32_t>( - {IBinder::DUMP_TRANSACTION, IBinder::PING_TRANSACTION, - IBinder::SHELL_COMMAND_TRANSACTION, IBinder::INTERFACE_TRANSACTION, - IBinder::SYSPROPS_TRANSACTION, IBinder::EXTENSION_TRANSACTION, - IBinder::TWEET_TRANSACTION, IBinder::LIKE_TRANSACTION}); + uint32_t code = getCode(provider); uint32_t flags = provider.ConsumeIntegral<uint32_t>(); Parcel data; // for increased fuzz coverage diff --git a/libs/binder/trusty/RpcTransportTipcTrusty.cpp b/libs/binder/trusty/RpcTransportTipcTrusty.cpp index c74ba0a65e..65ad896026 100644 --- a/libs/binder/trusty/RpcTransportTipcTrusty.cpp +++ b/libs/binder/trusty/RpcTransportTipcTrusty.cpp @@ -47,6 +47,71 @@ public: return mHaveMessage ? OK : WOULD_BLOCK; } + void moveMsgStart(ipc_msg_t* msg, size_t msg_size, size_t offset) { + LOG_ALWAYS_FATAL_IF(offset > msg_size, "tried to move message past its end %zd>%zd", offset, + msg_size); + while (true) { + if (offset == 0) { + break; + } + if (offset >= msg->iov[0].iov_len) { + // Move to the next iov, this one was sent already + offset -= msg->iov[0].iov_len; + msg->iov++; + msg->num_iov -= 1; + } else { + // We need to move the base of the current iov + msg->iov[0].iov_len -= offset; + msg->iov[0].iov_base = static_cast<char*>(msg->iov[0].iov_base) + offset; + offset = 0; + } + } + // We only send handles on the first message. This can be changed in the future if we want + // to send more handles than the maximum per message limit (which would require sending + // multiple messages). The current code makes sure that we send less handles than the + // maximum trusty allows. + msg->num_handles = 0; + } + + status_t sendTrustyMsg(ipc_msg_t* msg, size_t msg_size) { + do { + ssize_t rc = send_msg(mSocket.fd.get(), msg); + if (rc == ERR_NOT_ENOUGH_BUFFER) { + // Peer is blocked, wait until it unblocks. + // TODO: when tipc supports a send-unblocked handler, + // save the message here in a queue and retry it asynchronously + // when the handler gets called by the library + uevent uevt; + do { + rc = ::wait(mSocket.fd.get(), &uevt, INFINITE_TIME); + if (rc < 0) { + return statusFromTrusty(rc); + } + if (uevt.event & IPC_HANDLE_POLL_HUP) { + return DEAD_OBJECT; + } + } while (!(uevt.event & IPC_HANDLE_POLL_SEND_UNBLOCKED)); + + // Retry the send, it should go through this time because + // sending is now unblocked + rc = send_msg(mSocket.fd.get(), msg); + } + if (rc < 0) { + return statusFromTrusty(rc); + } + size_t sent_bytes = static_cast<size_t>(rc); + if (sent_bytes < msg_size) { + moveMsgStart(msg, msg_size, static_cast<size_t>(sent_bytes)); + msg_size -= sent_bytes; + } else { + LOG_ALWAYS_FATAL_IF(static_cast<size_t>(rc) != msg_size, + "Sent the wrong number of bytes %zd!=%zu", rc, msg_size); + break; + } + } while (true); + return OK; + } + status_t interruptableWriteFully( FdTrigger* /*fdTrigger*/, iovec* iovs, int niovs, const std::optional<SmallFunction<status_t()>>& /*altPoll*/, @@ -86,34 +151,7 @@ public: msg.handles = msgHandles; } - ssize_t rc = send_msg(mSocket.fd.get(), &msg); - if (rc == ERR_NOT_ENOUGH_BUFFER) { - // Peer is blocked, wait until it unblocks. - // TODO: when tipc supports a send-unblocked handler, - // save the message here in a queue and retry it asynchronously - // when the handler gets called by the library - uevent uevt; - do { - rc = ::wait(mSocket.fd.get(), &uevt, INFINITE_TIME); - if (rc < 0) { - return statusFromTrusty(rc); - } - if (uevt.event & IPC_HANDLE_POLL_HUP) { - return DEAD_OBJECT; - } - } while (!(uevt.event & IPC_HANDLE_POLL_SEND_UNBLOCKED)); - - // Retry the send, it should go through this time because - // sending is now unblocked - rc = send_msg(mSocket.fd.get(), &msg); - } - if (rc < 0) { - return statusFromTrusty(rc); - } - LOG_ALWAYS_FATAL_IF(static_cast<size_t>(rc) != size, - "Sent the wrong number of bytes %zd!=%zu", rc, size); - - return OK; + return sendTrustyMsg(&msg, size); } status_t interruptableReadFully( diff --git a/libs/binder/trusty/binderRpcTest/manifest.json b/libs/binder/trusty/binderRpcTest/manifest.json index 6e20b8a7ad..da0f2ed2d8 100644 --- a/libs/binder/trusty/binderRpcTest/manifest.json +++ b/libs/binder/trusty/binderRpcTest/manifest.json @@ -1,6 +1,6 @@ { "uuid": "9dbe9fb8-60fd-4bdd-af86-03e95d7ad78b", "app_name": "binderRpcTest", - "min_heap": 262144, + "min_heap": 4194304, "min_stack": 20480 } diff --git a/libs/binder/trusty/binderRpcTest/service/manifest.json b/libs/binder/trusty/binderRpcTest/service/manifest.json index d2a1fc0a48..55ff49c0b8 100644 --- a/libs/binder/trusty/binderRpcTest/service/manifest.json +++ b/libs/binder/trusty/binderRpcTest/service/manifest.json @@ -1,7 +1,7 @@ { "uuid": "87e424e5-69d7-4bbd-8b7c-7e24812cbc94", "app_name": "binderRpcTestService", - "min_heap": 65536, + "min_heap": 4194304, "min_stack": 20480, "mgmt_flags": { "restart_on_exit": true, diff --git a/libs/binder/trusty/include/binder/RpcServerTrusty.h b/libs/binder/trusty/include/binder/RpcServerTrusty.h index 583ad015e1..127676bf9a 100644 --- a/libs/binder/trusty/include/binder/RpcServerTrusty.h +++ b/libs/binder/trusty/include/binder/RpcServerTrusty.h @@ -94,9 +94,8 @@ private: static sp<RpcServer> makeRpcServer(std::unique_ptr<RpcTransportCtx> ctx) { auto rpcServer = sp<RpcServer>::make(std::move(ctx)); - // TODO(b/266741352): follow-up to prevent needing this in the future - // Trusty needs to be set to the latest stable version that is in prebuilts there. - LOG_ALWAYS_FATAL_IF(!rpcServer->setProtocolVersion(0)); + // By default we use the latest stable version. + LOG_ALWAYS_FATAL_IF(!rpcServer->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION)); return rpcServer; } diff --git a/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/ARpcServerTrusty.cpp b/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/ARpcServerTrusty.cpp index 451383a90a..12e347e4f3 100644 --- a/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/ARpcServerTrusty.cpp +++ b/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/ARpcServerTrusty.cpp @@ -27,6 +27,13 @@ using android::RpcTransportCtxFactoryTipcTrusty; using android::sp; using android::wp; +// The default behavior in trusty is to allow handles to be passed with tipc IPC. +// We add mode NONE so that servers do not reject connections from clients who do +// not change their default transport mode. +static const std::vector<RpcSession::FileDescriptorTransportMode> TRUSTY_SERVER_SUPPORTED_FD_MODES = + {RpcSession::FileDescriptorTransportMode::TRUSTY, + RpcSession::FileDescriptorTransportMode::NONE}; + struct ARpcServerTrusty { sp<RpcServer> mRpcServer; @@ -53,6 +60,8 @@ ARpcServerTrusty* ARpcServerTrusty_newPerSession(AIBinder* (*cb)(const void*, si return nullptr; } + rpcServer->setSupportedFileDescriptorTransportModes(TRUSTY_SERVER_SUPPORTED_FD_MODES); + rpcServer->setPerSessionRootObject( [cb, cbArgSp](wp<RpcSession> /*session*/, const void* addrPtr, size_t len) { auto* aib = (*cb)(addrPtr, len, cbArgSp.get()); diff --git a/libs/binder/trusty/rust/binder_rpc_test/binder_rpc_test_session/lib.rs b/libs/binder/trusty/rust/binder_rpc_test/binder_rpc_test_session/lib.rs index 22cba44975..caf3117195 100644 --- a/libs/binder/trusty/rust/binder_rpc_test/binder_rpc_test_session/lib.rs +++ b/libs/binder/trusty/rust/binder_rpc_test/binder_rpc_test_session/lib.rs @@ -82,6 +82,9 @@ impl IBinderRpcTest for MyBinderRpcSession { fn repeatBinder(&self, _binder: Option<&SpIBinder>) -> Result<Option<SpIBinder>, Status> { todo!() } + fn repeatBytes(&self, _bytes: &[u8]) -> Result<Vec<u8>, Status> { + todo!() + } fn holdBinder(&self, _binder: Option<&SpIBinder>) -> Result<(), Status> { todo!() } diff --git a/libs/binder/trusty/rust/binder_rpc_test/service/main.rs b/libs/binder/trusty/rust/binder_rpc_test/service/main.rs index c4a758a214..6f454be2b6 100644 --- a/libs/binder/trusty/rust/binder_rpc_test/service/main.rs +++ b/libs/binder/trusty/rust/binder_rpc_test/service/main.rs @@ -96,6 +96,9 @@ impl IBinderRpcTest for TestService { None => Err(Status::from(StatusCode::BAD_VALUE)), } } + fn repeatBytes(&self, _bytes: &[u8]) -> Result<Vec<u8>, Status> { + todo!() + } fn holdBinder(&self, binder: Option<&SpIBinder>) -> Result<(), Status> { *HOLD_BINDER.lock().unwrap() = binder.cloned(); Ok(()) diff --git a/libs/binder/trusty/rust/binder_rpc_unstable_bindgen/rules.mk b/libs/binder/trusty/rust/binder_rpc_unstable_bindgen/rules.mk index ef1b7c3cf8..40fc21867d 100644 --- a/libs/binder/trusty/rust/binder_rpc_unstable_bindgen/rules.mk +++ b/libs/binder/trusty/rust/binder_rpc_unstable_bindgen/rules.mk @@ -30,6 +30,8 @@ MODULE_LIBRARY_DEPS += \ trusty/user/base/lib/libstdc++-trusty \ trusty/user/base/lib/trusty-sys \ +MODULE_SRCDEPS := $(LIBBINDER_DIR)/include_rpc_unstable/binder_rpc_unstable.hpp + MODULE_BINDGEN_SRC_HEADER := $(LOCAL_DIR)/BinderBindings.hpp MODULE_BINDGEN_FLAGS += \ diff --git a/libs/binderdebug/stats.cpp b/libs/binderdebug/stats.cpp index 9c26afaa97..972fbd5295 100644 --- a/libs/binderdebug/stats.cpp +++ b/libs/binderdebug/stats.cpp @@ -22,9 +22,9 @@ #include <inttypes.h> -namespace android { +int main() { + using namespace android; -extern "C" int main() { // ignore args - we only print csv // we should use a csv library here for escaping, because @@ -58,5 +58,3 @@ extern "C" int main() { } return 0; } - -} // namespace android diff --git a/libs/binderdebug/tests/binderdebug_test.cpp b/libs/binderdebug/tests/binderdebug_test.cpp index ea799c06a2..ad2b581abc 100644 --- a/libs/binderdebug/tests/binderdebug_test.cpp +++ b/libs/binderdebug/tests/binderdebug_test.cpp @@ -60,8 +60,15 @@ TEST(BinderDebugTests, BinderThreads) { EXPECT_GE(pidInfo.threadCount, 1); } -extern "C" { +} // namespace test +} // namespace binderdebug +} // namespace android + int main(int argc, char** argv) { + using namespace android; + using namespace android::binderdebug; + using namespace android::binderdebug::test; + ::testing::InitGoogleTest(&argc, argv); // Create a child/client process to call into the main process so we can ensure @@ -84,7 +91,3 @@ int main(int argc, char** argv) { return RUN_ALL_TESTS(); } -} // extern "C" -} // namespace test -} // namespace binderdebug -} // namespace android diff --git a/libs/debugstore/rust/src/core.rs b/libs/debugstore/rust/src/core.rs index 6bf79d4e57..16147dd092 100644 --- a/libs/debugstore/rust/src/core.rs +++ b/libs/debugstore/rust/src/core.rs @@ -48,7 +48,7 @@ impl DebugStore { /// /// This constant is used as a part of the debug store's data format, /// allowing for version tracking and compatibility checks. - const ENCODE_VERSION: u32 = 1; + const ENCODE_VERSION: u32 = 3; /// Creates a new instance of `DebugStore` with specified event limit and maximum delay. fn new() -> Self { @@ -123,20 +123,25 @@ impl DebugStore { impl fmt::Display for DebugStore { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Write the debug store header information let uptime_now = uptimeMillis(); write!(f, "{},{},{}::", Self::ENCODE_VERSION, self.event_store.len(), uptime_now)?; + // Join events with a separator write!( f, "{}", - self.event_store.fold(String::new(), |mut acc, event| { + self.event_store.rfold(String::new(), |mut acc, event| { if !acc.is_empty() { acc.push_str("||"); } acc.push_str(&event.to_string()); acc }) - ) + )?; + + // Write the debug store footer + write!(f, ";;") } } diff --git a/libs/debugstore/rust/src/storage.rs b/libs/debugstore/rust/src/storage.rs index 2ad7f4e0b4..47760f3f21 100644 --- a/libs/debugstore/rust/src/storage.rs +++ b/libs/debugstore/rust/src/storage.rs @@ -32,14 +32,18 @@ impl<T, const N: usize> Storage<T, N> { self.insertion_buffer.force_push(value); } - /// Folds over the elements in the storage using the provided function. - pub fn fold<U, F>(&self, init: U, mut func: F) -> U + /// Folds over the elements in the storage in reverse order using the provided function. + pub fn rfold<U, F>(&self, init: U, mut func: F) -> U where F: FnMut(U, &T) -> U, { - let mut acc = init; + let mut items = Vec::new(); while let Some(value) = self.insertion_buffer.pop() { - acc = func(acc, &value); + items.push(value); + } + let mut acc = init; + for value in items.iter().rev() { + acc = func(acc, value); } acc } @@ -59,18 +63,18 @@ mod tests { let storage = Storage::<i32, 10>::new(); storage.insert(7); - let sum = storage.fold(0, |acc, &x| acc + x); + let sum = storage.rfold(0, |acc, &x| acc + x); assert_eq!(sum, 7, "The sum of the elements should be equal to the inserted value."); } #[test] - fn test_fold_functionality() { + fn test_rfold_functionality() { let storage = Storage::<i32, 5>::new(); storage.insert(1); storage.insert(2); storage.insert(3); - let sum = storage.fold(0, |acc, &x| acc + x); + let sum = storage.rfold(0, |acc, &x| acc + x); assert_eq!( sum, 6, "The sum of the elements should be equal to the sum of inserted values." @@ -84,13 +88,13 @@ mod tests { storage.insert(2); storage.insert(5); - let first_sum = storage.fold(0, |acc, &x| acc + x); + let first_sum = storage.rfold(0, |acc, &x| acc + x); assert_eq!(first_sum, 8, "The sum of the elements should be equal to the inserted values."); storage.insert(30); storage.insert(22); - let second_sum = storage.fold(0, |acc, &x| acc + x); + let second_sum = storage.rfold(0, |acc, &x| acc + x); assert_eq!( second_sum, 52, "The sum of the elements should be equal to the inserted values." @@ -103,7 +107,7 @@ mod tests { storage.insert(1); // This value should overwrite the previously inserted value (1). storage.insert(4); - let sum = storage.fold(0, |acc, &x| acc + x); + let sum = storage.rfold(0, |acc, &x| acc + x); assert_eq!(sum, 4, "The sum of the elements should be equal to the inserted values."); } @@ -128,7 +132,24 @@ mod tests { thread.join().expect("Thread should finish without panicking"); } - let count = storage.fold(0, |acc, _| acc + 1); + let count = storage.rfold(0, |acc, _| acc + 1); assert_eq!(count, 100, "Storage should be filled to its limit with concurrent insertions."); } + + #[test] + fn test_rfold_order() { + let storage = Storage::<i32, 5>::new(); + storage.insert(1); + storage.insert(2); + storage.insert(3); + + let mut result = Vec::new(); + storage.rfold((), |_, &x| result.push(x)); + + assert_eq!( + result, + vec![3, 2, 1], + "Elements should be processed in reverse order of insertion" + ); + } } diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp index a9bd11e41d..43ee33eb86 100644 --- a/libs/dumputils/dump_utils.cpp +++ b/libs/dumputils/dump_utils.cpp @@ -101,7 +101,7 @@ static const std::vector<std::string> aidl_interfaces_to_dump { "android.hardware.automotive.remoteaccess.IRemoteAccess", "android.hardware.automotive.vehicle.IVehicle", "android.hardware.biometrics.face.IBiometricsFace", - "android.hardware.biometrics.fingerprint.IBiometricsFingerprint", + "android.hardware.biometrics.fingerprint.IFingerprint", "android.hardware.camera.provider.ICameraProvider", "android.hardware.drm.IDrmFactory", "android.hardware.graphics.allocator.IAllocator", diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp index 368f5e079c..5244442ff3 100644 --- a/libs/ftl/Android.bp +++ b/libs/ftl/Android.bp @@ -21,10 +21,12 @@ cc_test { "enum_test.cpp", "expected_test.cpp", "fake_guard_test.cpp", + "finalizer_test.cpp", "flags_test.cpp", "function_test.cpp", "future_test.cpp", "hash_test.cpp", + "ignore_test.cpp", "match_test.cpp", "mixins_test.cpp", "non_null_test.cpp", diff --git a/libs/ftl/finalizer_test.cpp b/libs/ftl/finalizer_test.cpp new file mode 100644 index 0000000000..4f5c2258db --- /dev/null +++ b/libs/ftl/finalizer_test.cpp @@ -0,0 +1,209 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <memory> +#include <type_traits> +#include <utility> + +#include <ftl/finalizer.h> +#include <gtest/gtest.h> + +namespace android::test { + +namespace { + +struct Counter { + constexpr auto increment_fn() { + return [this] { ++value_; }; + } + + auto increment_finalizer() { + return ftl::Finalizer([this] { ++value_; }); + } + + [[nodiscard]] constexpr auto value() const -> int { return value_; } + + private: + int value_ = 0; +}; + +struct CounterPair { + constexpr auto increment_first_fn() { return first.increment_fn(); } + constexpr auto increment_second_fn() { return second.increment_fn(); } + [[nodiscard]] constexpr auto values() const -> std::pair<int, int> { + return {first.value(), second.value()}; + } + + private: + Counter first; + Counter second; +}; + +} // namespace + +TEST(Finalizer, DefaultConstructionAndNoOpDestructionWhenPolymorphicType) { + ftl::FinalizerStd finalizer1; + ftl::FinalizerFtl finalizer2; + ftl::FinalizerFtl1 finalizer3; + ftl::FinalizerFtl2 finalizer4; + ftl::FinalizerFtl3 finalizer5; +} + +TEST(Finalizer, InvokesTheFunctionOnDestruction) { + Counter counter; + { + const auto finalizer = counter.increment_finalizer(); + EXPECT_EQ(counter.value(), 0); + } + EXPECT_EQ(counter.value(), 1); +} + +TEST(Finalizer, InvocationCanBeCanceled) { + Counter counter; + { + auto finalizer = counter.increment_finalizer(); + EXPECT_EQ(counter.value(), 0); + finalizer.cancel(); + EXPECT_EQ(counter.value(), 0); + } + EXPECT_EQ(counter.value(), 0); +} + +TEST(Finalizer, InvokesTheFunctionOnce) { + Counter counter; + { + auto finalizer = counter.increment_finalizer(); + EXPECT_EQ(counter.value(), 0); + finalizer(); + EXPECT_EQ(counter.value(), 1); + finalizer(); + EXPECT_EQ(counter.value(), 1); + } + EXPECT_EQ(counter.value(), 1); +} + +TEST(Finalizer, SelfInvocationIsAllowedAndANoOp) { + Counter counter; + ftl::FinalizerStd finalizer; + finalizer = ftl::Finalizer([&]() { + counter.increment_fn()(); + finalizer(); // recursive invocation should do nothing. + }); + EXPECT_EQ(counter.value(), 0); + finalizer(); + EXPECT_EQ(counter.value(), 1); +} + +TEST(Finalizer, MoveConstruction) { + Counter counter; + { + ftl::FinalizerStd outer_finalizer = counter.increment_finalizer(); + EXPECT_EQ(counter.value(), 0); + { + ftl::FinalizerStd inner_finalizer = std::move(outer_finalizer); + static_assert(std::is_same_v<decltype(inner_finalizer), decltype(outer_finalizer)>); + EXPECT_EQ(counter.value(), 0); + } + EXPECT_EQ(counter.value(), 1); + } + EXPECT_EQ(counter.value(), 1); +} + +TEST(Finalizer, MoveConstructionWithImplicitConversion) { + Counter counter; + { + auto outer_finalizer = counter.increment_finalizer(); + EXPECT_EQ(counter.value(), 0); + { + ftl::FinalizerStd inner_finalizer = std::move(outer_finalizer); + static_assert(!std::is_same_v<decltype(inner_finalizer), decltype(outer_finalizer)>); + EXPECT_EQ(counter.value(), 0); + } + EXPECT_EQ(counter.value(), 1); + } + EXPECT_EQ(counter.value(), 1); +} + +TEST(Finalizer, MoveAssignment) { + CounterPair pair; + { + ftl::FinalizerStd outer_finalizer = ftl::Finalizer(pair.increment_first_fn()); + EXPECT_EQ(pair.values(), std::make_pair(0, 0)); + + { + ftl::FinalizerStd inner_finalizer = ftl::Finalizer(pair.increment_second_fn()); + static_assert(std::is_same_v<decltype(inner_finalizer), decltype(outer_finalizer)>); + EXPECT_EQ(pair.values(), std::make_pair(0, 0)); + inner_finalizer = std::move(outer_finalizer); + EXPECT_EQ(pair.values(), std::make_pair(0, 1)); + } + EXPECT_EQ(pair.values(), std::make_pair(1, 1)); + } + EXPECT_EQ(pair.values(), std::make_pair(1, 1)); +} + +TEST(Finalizer, MoveAssignmentWithImplicitConversion) { + CounterPair pair; + { + auto outer_finalizer = ftl::Finalizer(pair.increment_first_fn()); + EXPECT_EQ(pair.values(), std::make_pair(0, 0)); + + { + ftl::FinalizerStd inner_finalizer = ftl::Finalizer(pair.increment_second_fn()); + static_assert(!std::is_same_v<decltype(inner_finalizer), decltype(outer_finalizer)>); + EXPECT_EQ(pair.values(), std::make_pair(0, 0)); + inner_finalizer = std::move(outer_finalizer); + EXPECT_EQ(pair.values(), std::make_pair(0, 1)); + } + EXPECT_EQ(pair.values(), std::make_pair(1, 1)); + } + EXPECT_EQ(pair.values(), std::make_pair(1, 1)); +} + +TEST(Finalizer, NullifiesTheFunctionWhenInvokedIfPossible) { + auto shared = std::make_shared<int>(0); + std::weak_ptr<int> weak = shared; + + int count = 0; + { + auto lambda = [capture = std::move(shared)]() {}; + auto finalizer = ftl::Finalizer(std::move(lambda)); + EXPECT_FALSE(weak.expired()); + + // A lambda is not nullable. Invoking the finalizer cannot destroy it to destroy the lambda's + // capture. + finalizer(); + EXPECT_FALSE(weak.expired()); + } + // The lambda is only destroyed when the finalizer instance is destroyed. + EXPECT_TRUE(weak.expired()); + + shared = std::make_shared<int>(0); + weak = shared; + + { + auto lambda = [capture = std::move(shared)]() {}; + auto finalizer = ftl::FinalizerStd(std::move(lambda)); + EXPECT_FALSE(weak.expired()); + + // Since std::function is used, and is nullable, invoking the finalizer will destroy the + // contained function, which will destroy the lambda's capture. + finalizer(); + EXPECT_TRUE(weak.expired()); + } +} + +} // namespace android::test diff --git a/libs/ftl/ignore_test.cpp b/libs/ftl/ignore_test.cpp new file mode 100644 index 0000000000..5d5c67b8b1 --- /dev/null +++ b/libs/ftl/ignore_test.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string> + +#include <ftl/ignore.h> +#include <gtest/gtest.h> + +namespace android::test { +namespace { + +// Keep in sync with the example usage in the header file. + +void ftl_ignore_multiple(int arg1, const char* arg2, std::string arg3) { + // When invoked, all the arguments are ignored. + ftl::ignore(arg1, arg2, arg3); +} + +void ftl_ignore_single(int arg) { + // It can be used like std::ignore to ignore a single value + ftl::ignore = arg; +} + +} // namespace + +TEST(Ignore, Example) { + // The real example test is that there are no compiler warnings for unused arguments above. + + // Use the example functions to avoid a compiler warning about unused functions. + ftl_ignore_multiple(0, "a", "b"); + ftl_ignore_single(0); +} + +} // namespace android::test diff --git a/libs/graphicsenv/Android.bp b/libs/graphicsenv/Android.bp index af50a2980c..dce7778229 100644 --- a/libs/graphicsenv/Android.bp +++ b/libs/graphicsenv/Android.bp @@ -21,10 +21,27 @@ package { default_applicable_licenses: ["frameworks_native_license"], } +aconfig_declarations { + name: "graphicsenv_flags", + package: "com.android.graphics.graphicsenv.flags", + container: "system", + srcs: ["graphicsenv_flags.aconfig"], +} + +cc_aconfig_library { + name: "graphicsenv_flags_c_lib", + aconfig_declarations: "graphicsenv_flags", +} + cc_library_shared { name: "libgraphicsenv", + defaults: [ + "aconfig_lib_cc_static_link.defaults", + ], + srcs: [ + "FeatureOverrides.cpp", "GpuStatsInfo.cpp", "GraphicsEnv.cpp", "IGpuService.cpp", @@ -35,6 +52,10 @@ cc_library_shared { "-Werror", ], + static_libs: [ + "graphicsenv_flags_c_lib", + ], + shared_libs: [ "libbase", "libbinder", @@ -42,6 +63,7 @@ cc_library_shared { "libdl_android", "liblog", "libutils", + "server_configurable_flags", ], header_libs: [ diff --git a/libs/graphicsenv/FeatureOverrides.cpp b/libs/graphicsenv/FeatureOverrides.cpp new file mode 100644 index 0000000000..9e7a4cf4a1 --- /dev/null +++ b/libs/graphicsenv/FeatureOverrides.cpp @@ -0,0 +1,209 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cinttypes> + +#include <android-base/stringprintf.h> +#include <binder/Parcel.h> +#include <graphicsenv/FeatureOverrides.h> + +namespace android { + +using base::StringAppendF; + +status_t FeatureConfig::writeToParcel(Parcel* parcel) const { + status_t status; + + status = parcel->writeUtf8AsUtf16(mFeatureName); + if (status != OK) { + return status; + } + status = parcel->writeBool(mEnabled); + if (status != OK) { + return status; + } + // Number of GPU vendor IDs. + status = parcel->writeVectorSize(mGpuVendorIDs); + if (status != OK) { + return status; + } + // GPU vendor IDs. + for (const auto& vendorID : mGpuVendorIDs) { + status = parcel->writeUint32(vendorID); + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t FeatureConfig::readFromParcel(const Parcel* parcel) { + status_t status; + + status = parcel->readUtf8FromUtf16(&mFeatureName); + if (status != OK) { + return status; + } + status = parcel->readBool(&mEnabled); + if (status != OK) { + return status; + } + // Number of GPU vendor IDs. + int numGpuVendorIDs; + status = parcel->readInt32(&numGpuVendorIDs); + if (status != OK) { + return status; + } + // GPU vendor IDs. + for (int i = 0; i < numGpuVendorIDs; i++) { + uint32_t gpuVendorIdUint; + status = parcel->readUint32(&gpuVendorIdUint); + if (status != OK) { + return status; + } + mGpuVendorIDs.emplace_back(gpuVendorIdUint); + } + + return OK; +} + +std::string FeatureConfig::toString() const { + std::string result; + StringAppendF(&result, "Feature: %s\n", mFeatureName.c_str()); + StringAppendF(&result, " Status: %s\n", mEnabled ? "enabled" : "disabled"); + for (const auto& vendorID : mGpuVendorIDs) { + // vkjson outputs decimal, so print both formats. + StringAppendF(&result, " GPU Vendor ID: 0x%04X (%d)\n", vendorID, vendorID); + } + + return result; +} + +status_t FeatureOverrides::writeToParcel(Parcel* parcel) const { + status_t status; + // Number of global feature configs. + status = parcel->writeVectorSize(mGlobalFeatures); + if (status != OK) { + return status; + } + // Global feature configs. + for (const auto& cfg : mGlobalFeatures) { + status = cfg.writeToParcel(parcel); + if (status != OK) { + return status; + } + } + // Number of package feature overrides. + status = parcel->writeInt32(static_cast<int32_t>(mPackageFeatures.size())); + if (status != OK) { + return status; + } + for (const auto& feature : mPackageFeatures) { + // Package name. + status = parcel->writeUtf8AsUtf16(feature.first); + if (status != OK) { + return status; + } + // Number of package feature configs. + status = parcel->writeVectorSize(feature.second); + if (status != OK) { + return status; + } + // Package feature configs. + for (const auto& cfg : feature.second) { + status = cfg.writeToParcel(parcel); + if (status != OK) { + return status; + } + } + } + + return OK; +} + +status_t FeatureOverrides::readFromParcel(const Parcel* parcel) { + status_t status; + + // Number of global feature configs. + status = parcel->resizeOutVector(&mGlobalFeatures); + if (status != OK) { + return status; + } + // Global feature configs. + for (FeatureConfig& cfg : mGlobalFeatures) { + status = cfg.readFromParcel(parcel); + if (status != OK) { + return status; + } + } + + // Number of package feature overrides. + int numPkgOverrides; + status = parcel->readInt32(&numPkgOverrides); + if (status != OK) { + return status; + } + // Package feature overrides. + for (int i = 0; i < numPkgOverrides; i++) { + // Package name. + std::string name; + status = parcel->readUtf8FromUtf16(&name); + if (status != OK) { + return status; + } + std::vector<FeatureConfig> cfgs; + // Number of package feature configs. + int numCfgs; + status = parcel->readInt32(&numCfgs); + if (status != OK) { + return status; + } + // Package feature configs. + for (int j = 0; j < numCfgs; j++) { + FeatureConfig cfg; + status = cfg.readFromParcel(parcel); + if (status != OK) { + return status; + } + cfgs.emplace_back(cfg); + } + mPackageFeatures[name] = cfgs; + } + + return OK; +} + +std::string FeatureOverrides::toString() const { + std::string result; + result.append("Global Features:\n"); + for (auto& cfg : mGlobalFeatures) { + result.append(" " + cfg.toString()); + } + result.append("\n"); + result.append("Package Features:\n"); + for (const auto& packageFeature : mPackageFeatures) { + result.append(" Package:"); + StringAppendF(&result, " %s\n", packageFeature.first.c_str()); + for (auto& cfg : packageFeature.second) { + result.append(" " + cfg.toString()); + } + } + + return result; +} + +} // namespace android diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp index a8d5fe7371..03e6456ea6 100644 --- a/libs/graphicsenv/GraphicsEnv.cpp +++ b/libs/graphicsenv/GraphicsEnv.cpp @@ -29,6 +29,7 @@ #include <android-base/strings.h> #include <android/dlext.h> #include <binder/IServiceManager.h> +#include <com_android_graphics_graphicsenv_flags.h> #include <graphicsenv/IGpuService.h> #include <log/log.h> #include <nativeloader/dlext_namespaces.h> @@ -70,6 +71,8 @@ static bool isVndkEnabled() { } } // namespace +namespace graphicsenv_flags = com::android::graphics::graphicsenv::flags; + namespace android { enum NativeLibrary { @@ -596,7 +599,7 @@ bool GraphicsEnv::shouldUseAngle() { // If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless. void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseNativeDriver, const std::string& packageName, - const std::vector<std::string> eglFeatures) { + const std::vector<std::string>& eglFeatures) { if (mShouldUseAngle) { // ANGLE is already set up for this application process, even if the application // needs to switch from apk to system or vice versa, the application process must @@ -606,11 +609,11 @@ void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseNati return; } - mAngleEglFeatures = std::move(eglFeatures); + mAngleEglFeatures = eglFeatures; ALOGV("setting ANGLE path to '%s'", path.c_str()); - mAnglePath = std::move(path); + mAnglePath = path; ALOGV("setting app package name to '%s'", packageName.c_str()); - mPackageName = std::move(packageName); + mPackageName = packageName; if (mAnglePath == "system") { mShouldUseSystemAngle = true; } @@ -618,16 +621,62 @@ void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseNati mShouldUseAngle = true; } mShouldUseNativeDriver = shouldUseNativeDriver; + + if (mShouldUseAngle) { + updateAngleFeatureOverrides(); + } } std::string& GraphicsEnv::getPackageName() { return mPackageName; } +// List of ANGLE features to enable, specified in the Global.Settings value "angle_egl_features". const std::vector<std::string>& GraphicsEnv::getAngleEglFeatures() { return mAngleEglFeatures; } +// List of ANGLE features to override (enabled or disable). +// The list of overrides is loaded and parsed by GpuService. +void GraphicsEnv::updateAngleFeatureOverrides() { + if (!graphicsenv_flags::angle_feature_overrides()) { + return; + } + + const sp<IGpuService> gpuService = getGpuService(); + if (!gpuService) { + ALOGE("No GPU service"); + return; + } + + mFeatureOverrides = gpuService->getFeatureOverrides(); +} + +void GraphicsEnv::getAngleFeatureOverrides(std::vector<const char*>& enabled, + std::vector<const char*>& disabled) { + if (!graphicsenv_flags::angle_feature_overrides()) { + return; + } + + for (const FeatureConfig& feature : mFeatureOverrides.mGlobalFeatures) { + if (feature.mEnabled) { + enabled.push_back(feature.mFeatureName.c_str()); + } else { + disabled.push_back(feature.mFeatureName.c_str()); + } + } + + if (mFeatureOverrides.mPackageFeatures.count(mPackageName)) { + for (const FeatureConfig& feature : mFeatureOverrides.mPackageFeatures[mPackageName]) { + if (feature.mEnabled) { + enabled.push_back(feature.mFeatureName.c_str()); + } else { + disabled.push_back(feature.mFeatureName.c_str()); + } + } + } +} + android_namespace_t* GraphicsEnv::getAngleNamespace() { std::lock_guard<std::mutex> lock(mNamespaceMutex); diff --git a/libs/graphicsenv/IGpuService.cpp b/libs/graphicsenv/IGpuService.cpp index 42e7c378a9..9a34aff299 100644 --- a/libs/graphicsenv/IGpuService.cpp +++ b/libs/graphicsenv/IGpuService.cpp @@ -119,6 +119,21 @@ public: } return driverPath; } + + FeatureOverrides getFeatureOverrides() override { + Parcel data, reply; + data.writeInterfaceToken(IGpuService::getInterfaceDescriptor()); + + FeatureOverrides featureOverrides; + status_t error = + remote()->transact(BnGpuService::GET_FEATURE_CONFIG_OVERRIDES, data, &reply); + if (error != OK) { + return featureOverrides; + } + + featureOverrides.readFromParcel(&reply); + return featureOverrides; + } }; IMPLEMENT_META_INTERFACE(GpuService, "android.graphicsenv.IGpuService"); @@ -271,6 +286,15 @@ status_t BnGpuService::onTransact(uint32_t code, const Parcel& data, Parcel* rep toggleAngleAsSystemDriver(enableAngleAsSystemDriver); return OK; } + case GET_FEATURE_CONFIG_OVERRIDES: { + CHECK_INTERFACE(IGpuService, data, reply); + + // Get the FeatureOverrides from gpuservice, which implements the IGpuService interface + // with GpuService::getFeatureOverrides(). + FeatureOverrides featureOverrides = getFeatureOverrides(); + featureOverrides.writeToParcel(reply); + return OK; + } default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/graphicsenv/graphicsenv_flags.aconfig b/libs/graphicsenv/graphicsenv_flags.aconfig new file mode 100644 index 0000000000..efa4bca892 --- /dev/null +++ b/libs/graphicsenv/graphicsenv_flags.aconfig @@ -0,0 +1,9 @@ +package: "com.android.graphics.graphicsenv.flags" +container: "system" + +flag { + name: "angle_feature_overrides" + namespace: "gpu" + description: "This flag controls the ANGLE Feature Overrides in GraphicsEnv." + bug: "372694741" +} diff --git a/libs/graphicsenv/include/graphicsenv/FeatureOverrides.h b/libs/graphicsenv/include/graphicsenv/FeatureOverrides.h new file mode 100644 index 0000000000..5dc613b901 --- /dev/null +++ b/libs/graphicsenv/include/graphicsenv/FeatureOverrides.h @@ -0,0 +1,59 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <map> +#include <string> +#include <vector> + +#include <binder/Parcelable.h> + +namespace android { + +class FeatureConfig : public Parcelable { +public: + FeatureConfig() = default; + FeatureConfig(const FeatureConfig&) = default; + virtual ~FeatureConfig() = default; + virtual status_t writeToParcel(Parcel* parcel) const; + virtual status_t readFromParcel(const Parcel* parcel); + std::string toString() const; + + std::string mFeatureName; + bool mEnabled; + std::vector<uint32_t> mGpuVendorIDs; +}; + +/* + * Class for transporting OpenGL ES Feature configurations from GpuService to authorized + * recipients. + */ +class FeatureOverrides : public Parcelable { +public: + FeatureOverrides() = default; + FeatureOverrides(const FeatureOverrides&) = default; + virtual ~FeatureOverrides() = default; + virtual status_t writeToParcel(Parcel* parcel) const; + virtual status_t readFromParcel(const Parcel* parcel); + std::string toString() const; + + std::vector<FeatureConfig> mGlobalFeatures; + /* Key: Package Name, Value: Package's Feature Configs */ + std::map<std::string, std::vector<FeatureConfig>> mPackageFeatures; +}; + +} // namespace android diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h index b0ab0b9d22..68219008e8 100644 --- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h +++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h @@ -17,6 +17,7 @@ #ifndef ANDROID_UI_GRAPHICS_ENV_H #define ANDROID_UI_GRAPHICS_ENV_H 1 +#include <graphicsenv/FeatureOverrides.h> #include <graphicsenv/GpuStatsInfo.h> #include <mutex> @@ -114,12 +115,15 @@ public: // If shouldUseNativeDriver is true, it means native GLES drivers must be used for the process. // If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless. void setAngleInfo(const std::string& path, const bool shouldUseNativeDriver, - const std::string& packageName, const std::vector<std::string> eglFeatures); + const std::string& packageName, const std::vector<std::string>& eglFeatures); // Get the ANGLE driver namespace. android_namespace_t* getAngleNamespace(); // Get the app package name. std::string& getPackageName(); const std::vector<std::string>& getAngleEglFeatures(); + void updateAngleFeatureOverrides(); + void getAngleFeatureOverrides(std::vector<const char*>& enabled, + std::vector<const char*>& disabled); // Set the persist.graphics.egl system property value. void nativeToggleAngleAsSystemDriver(bool enabled); bool shouldUseSystemAngle(); @@ -177,6 +181,7 @@ private: std::string mPackageName; // ANGLE EGL features; std::vector<std::string> mAngleEglFeatures; + FeatureOverrides mFeatureOverrides; // Whether ANGLE should be used. bool mShouldUseAngle = false; // Whether loader should load system ANGLE. diff --git a/libs/graphicsenv/include/graphicsenv/IGpuService.h b/libs/graphicsenv/include/graphicsenv/IGpuService.h index a0d6e37302..442683a3e9 100644 --- a/libs/graphicsenv/include/graphicsenv/IGpuService.h +++ b/libs/graphicsenv/include/graphicsenv/IGpuService.h @@ -18,6 +18,7 @@ #include <binder/IInterface.h> #include <cutils/compiler.h> +#include <graphicsenv/FeatureOverrides.h> #include <graphicsenv/GpuStatsInfo.h> #include <vector> @@ -55,6 +56,9 @@ public: // sets ANGLE as system GLES driver if enabled==true by setting persist.graphics.egl to true. virtual void toggleAngleAsSystemDriver(bool enabled) = 0; + + // Get the list of features to override. + virtual FeatureOverrides getFeatureOverrides() = 0; }; class BnGpuService : public BnInterface<IGpuService> { @@ -67,6 +71,7 @@ public: TOGGLE_ANGLE_AS_SYSTEM_DRIVER, SET_TARGET_STATS_ARRAY, ADD_VULKAN_ENGINE_NAME, + GET_FEATURE_CONFIG_OVERRIDES, // Always append new enum to the end. }; diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 052b519db6..b5fa321fc2 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -266,8 +266,6 @@ filegroup { "FenceMonitor.cpp", "Flags.cpp", "GLConsumer.cpp", - "IConsumerListener.cpp", - "IGraphicBufferConsumer.cpp", "IGraphicBufferProducer.cpp", "IProducerListener.cpp", "ISurfaceComposer.cpp", @@ -283,6 +281,7 @@ filegroup { "SurfaceControl.cpp", "SurfaceComposerClient.cpp", "SyncFeatures.cpp", + "TransactionState.cpp", "VsyncEventData.cpp", "view/Surface.cpp", "WindowInfosListenerReporter.cpp", diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 38465b0de2..1aae13c1f4 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -197,15 +197,15 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati mUpdateDestinationFrame(updateDestinationFrame) { createBufferQueue(&mProducer, &mConsumer); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) - mBufferItemConsumer = new BLASTBufferItemConsumer(mProducer, mConsumer, - GraphicBuffer::USAGE_HW_COMPOSER | - GraphicBuffer::USAGE_HW_TEXTURE, - 1, false, this); + mBufferItemConsumer = sp<BLASTBufferItemConsumer>::make(mProducer, mConsumer, + GraphicBuffer::USAGE_HW_COMPOSER | + GraphicBuffer::USAGE_HW_TEXTURE, + 1, false, this); #else - mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer, - GraphicBuffer::USAGE_HW_COMPOSER | - GraphicBuffer::USAGE_HW_TEXTURE, - 1, false, this); + mBufferItemConsumer = sp<BLASTBufferItemConsumer>::make(mConsumer, + GraphicBuffer::USAGE_HW_COMPOSER | + GraphicBuffer::USAGE_HW_TEXTURE, + 1, false, this); #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) // since the adapter is in the client process, set dequeue timeout // explicitly so that dequeueBuffer will block @@ -222,8 +222,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati ComposerServiceAIDL::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers); mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers); mCurrentMaxAcquiredBufferCount = mMaxAcquiredBuffers; - mNumAcquired = 0; - mNumFrameAvailable = 0; TransactionCompletedListener::getInstance()->addQueueStallListener( [&](const std::string& reason) { @@ -244,12 +242,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati BQA_LOGV("BLASTBufferQueue created"); } -BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, - int width, int height, int32_t format) - : BLASTBufferQueue(name) { - update(surface, width, height, format); -} - BLASTBufferQueue::~BLASTBufferQueue() { TransactionCompletedListener::getInstance()->removeQueueStallListener(this); if (mPendingTransactions.empty()) { @@ -421,14 +413,12 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence stat.frameEventStats.dequeueReadyTime); } auto currFrameNumber = stat.frameEventStats.frameNumber; - std::vector<ReleaseCallbackId> staleReleases; - for (const auto& [key, value]: mSubmitted) { - if (currFrameNumber > key.framenumber) { - staleReleases.push_back(key); + // Release stale buffers. + for (const auto& [key, _] : mSubmitted) { + if (currFrameNumber <= key.framenumber) { + continue; // not stale. } - } - for (const auto& staleRelease : staleReleases) { - releaseBufferCallbackLocked(staleRelease, + releaseBufferCallbackLocked(key, stat.previousReleaseFence ? stat.previousReleaseFence : Fence::NO_FENCE, @@ -447,7 +437,7 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence void BLASTBufferQueue::flushShadowQueue() { BQA_LOGV("flushShadowQueue"); - int numFramesToFlush = mNumFrameAvailable; + int32_t numFramesToFlush = mNumFrameAvailable; while (numFramesToFlush > 0) { acquireNextBufferLocked(std::nullopt); numFramesToFlush--; @@ -624,7 +614,7 @@ status_t BLASTBufferQueue::acquireNextBufferLocked( mNumAcquired++; mLastAcquiredFrameNumber = bufferItem.mFrameNumber; ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber); - mSubmitted[releaseCallbackId] = bufferItem; + mSubmitted.emplace_or_replace(releaseCallbackId, bufferItem); bool needsDisconnect = false; mBufferItemConsumer->getConnectionEvents(bufferItem.mFrameNumber, &needsDisconnect); @@ -647,7 +637,8 @@ status_t BLASTBufferQueue::acquireNextBufferLocked( bufferItem.mScalingMode, crop); auto releaseBufferCallback = makeReleaseBufferCallbackThunk(); - sp<Fence> fence = bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE; + sp<Fence> fence = + bufferItem.mFence ? sp<Fence>::make(bufferItem.mFence->dup()) : Fence::NO_FENCE; nsecs_t dequeueTime = -1; { @@ -857,7 +848,7 @@ void BLASTBufferQueue::onFrameReplaced(const BufferItem& item) { void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) { std::lock_guard _lock{mTimestampMutex}; - mDequeueTimestamps[bufferId] = systemTime(); + mDequeueTimestamps.emplace_or_replace(bufferId, systemTime()); }; void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) { @@ -946,15 +937,22 @@ public: : Surface(igbp, controlledByApp, scHandle), mBbq(bbq) {} void allocateBuffers() override { + ATRACE_CALL(); uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth; uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight; auto gbp = getIGraphicBufferProducer(); - std::thread ([reqWidth, reqHeight, gbp=getIGraphicBufferProducer(), - reqFormat=mReqFormat, reqUsage=mReqUsage] () { + std::thread allocateThread([reqWidth, reqHeight, gbp = getIGraphicBufferProducer(), + reqFormat = mReqFormat, reqUsage = mReqUsage]() { + if (com_android_graphics_libgui_flags_allocate_buffer_priority()) { + androidSetThreadName("allocateBuffers"); + pid_t tid = gettid(); + androidSetThreadPriority(tid, ANDROID_PRIORITY_DISPLAY); + } + gbp->allocateBuffers(reqWidth, reqHeight, reqFormat, reqUsage); - - }).detach(); + }); + allocateThread.detach(); } status_t setFrameRate(float frameRate, int8_t compatibility, @@ -1024,7 +1022,7 @@ sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) { if (includeSurfaceControlHandle && mSurfaceControl) { scHandle = mSurfaceControl->getHandle(); } - return new BBQSurface(mProducer, true, scHandle, this); + return sp<BBQSurface>::make(mProducer, true, scHandle, this); } void BLASTBufferQueue::mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, @@ -1130,10 +1128,10 @@ ANDROID_SINGLETON_STATIC_INSTANCE(AsyncWorker); class AsyncProducerListener : public BnProducerListener { private: const sp<IProducerListener> mListener; - -public: AsyncProducerListener(const sp<IProducerListener>& listener) : mListener(listener) {} + friend class sp<AsyncProducerListener>; +public: void onBufferReleased() override { AsyncWorker::getInstance().post([listener = mListener]() { listener->onBufferReleased(); }); } @@ -1187,7 +1185,7 @@ public: return BufferQueueProducer::connect(listener, api, producerControlledByApp, output); } - return BufferQueueProducer::connect(new AsyncProducerListener(listener), api, + return BufferQueueProducer::connect(sp<AsyncProducerListener>::make(listener), api, producerControlledByApp, output); } @@ -1227,16 +1225,12 @@ public: #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) status_t waitForBufferRelease(std::unique_lock<std::mutex>& bufferQueueLock, nsecs_t timeout) const override { + const auto startTime = std::chrono::steady_clock::now(); sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote(); if (!bbq) { return OK; } - // Provide a callback for Choreographer to start buffer stuffing recovery when blocked - // on buffer release. - std::function<void()> callbackCopy = bbq->getWaitForBufferReleaseCallback(); - if (callbackCopy) callbackCopy(); - // BufferQueue has already checked if we have a free buffer. If there's an unread interrupt, // we want to ignore it. This must be done before unlocking the BufferQueue lock to ensure // we don't miss an interrupt. @@ -1258,6 +1252,14 @@ public: } bbq->releaseBufferCallback(id, fence, maxAcquiredBufferCount); + const nsecs_t durationNanos = std::chrono::duration_cast<std::chrono::nanoseconds>( + std::chrono::steady_clock::now() - startTime) + .count(); + // Provide a callback for Choreographer to start buffer stuffing recovery when blocked + // on buffer release. + std::function<void(const nsecs_t)> callbackCopy = bbq->getWaitForBufferReleaseCallback(); + if (callbackCopy) callbackCopy(durationNanos); + return OK; } #endif @@ -1349,12 +1351,13 @@ void BLASTBufferQueue::setApplyToken(sp<IBinder> applyToken) { mApplyToken = std::move(applyToken); } -void BLASTBufferQueue::setWaitForBufferReleaseCallback(std::function<void()> callback) { +void BLASTBufferQueue::setWaitForBufferReleaseCallback( + std::function<void(const nsecs_t)> callback) { std::lock_guard _lock{mWaitForBufferReleaseMutex}; mWaitForBufferReleaseCallback = std::move(callback); } -std::function<void()> BLASTBufferQueue::getWaitForBufferReleaseCallback() const { +std::function<void(const nsecs_t)> BLASTBufferQueue::getWaitForBufferReleaseCallback() const { std::lock_guard _lock{mWaitForBufferReleaseMutex}; return mWaitForBufferReleaseCallback; } diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp index 3b2d337a21..9dcd5dc4c5 100644 --- a/libs/gui/BufferItem.cpp +++ b/libs/gui/BufferItem.cpp @@ -215,14 +215,14 @@ status_t BufferItem::unflatten( FlattenableUtils::read(buffer, size, flags); if (flags & 1) { - mGraphicBuffer = new GraphicBuffer(); + mGraphicBuffer = sp<GraphicBuffer>::make(); status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count); if (err) return err; size -= FlattenableUtils::align<4>(buffer); } if (flags & 2) { - mFence = new Fence(); + mFence = sp<Fence>::make(); status_t err = mFence->unflatten(buffer, size, fds, count); if (err) return err; size -= FlattenableUtils::align<4>(buffer); diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp index 8566419435..4926ceb619 100644 --- a/libs/gui/BufferItemConsumer.cpp +++ b/libs/gui/BufferItemConsumer.cpp @@ -17,6 +17,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "BufferItemConsumer" //#define ATRACE_TAG ATRACE_TAG_GRAPHICS +#include <utils/Errors.h> #include <utils/Log.h> #include <inttypes.h> @@ -24,6 +25,7 @@ #include <com_android_graphics_libgui_flags.h> #include <gui/BufferItem.h> #include <gui/BufferItemConsumer.h> +#include <gui/Surface.h> #include <ui/BufferQueueDefs.h> #include <ui/GraphicBuffer.h> @@ -35,6 +37,30 @@ namespace android { +std::tuple<sp<BufferItemConsumer>, sp<Surface>> BufferItemConsumer::create( + uint64_t consumerUsage, int bufferCount, bool controlledByApp, + bool isConsumerSurfaceFlinger) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) + sp<BufferItemConsumer> bufferItemConsumer = + sp<BufferItemConsumer>::make(consumerUsage, bufferCount, controlledByApp, + isConsumerSurfaceFlinger); + return {bufferItemConsumer, bufferItemConsumer->getSurface()}; +#else + sp<IGraphicBufferProducer> igbp; + sp<IGraphicBufferConsumer> igbc; + BufferQueue::createBufferQueue(&igbp, &igbc, isConsumerSurfaceFlinger); + sp<BufferItemConsumer> bufferItemConsumer = + sp<BufferItemConsumer>::make(igbc, consumerUsage, bufferCount, controlledByApp); + return {bufferItemConsumer, sp<Surface>::make(igbp, controlledByApp)}; +#endif +} + +sp<BufferItemConsumer> BufferItemConsumer::create(const sp<IGraphicBufferConsumer>& consumer, + uint64_t consumerUsage, int bufferCount, + bool controlledByApp) { + return sp<BufferItemConsumer>::make(consumer, consumerUsage, bufferCount, controlledByApp); +} + #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) BufferItemConsumer::BufferItemConsumer(uint64_t consumerUsage, int bufferCount, bool controlledByApp, bool isConsumerSurfaceFlinger) @@ -107,13 +133,36 @@ status_t BufferItemConsumer::acquireBuffer(BufferItem *item, return OK; } +status_t BufferItemConsumer::attachBuffer(const sp<GraphicBuffer>& buffer) { + if (!buffer) { + BI_LOGE("BufferItemConsumer::attachBuffer no input buffer specified."); + return BAD_VALUE; + } + + Mutex::Autolock _l(mMutex); + + int slot = INVALID_BUFFER_SLOT; + status_t status = mConsumer->attachBuffer(&slot, buffer); + if (status != OK) { + BI_LOGE("BufferItemConsumer::attachBuffer unable to attach buffer %d", status); + return status; + } + + mSlots[slot] = { + .mGraphicBuffer = buffer, + .mFence = nullptr, + .mFrameNumber = 0, + }; + + return OK; +} + status_t BufferItemConsumer::releaseBuffer(const BufferItem &item, const sp<Fence>& releaseFence) { Mutex::Autolock _l(mMutex); return releaseBufferSlotLocked(item.mSlot, item.mGraphicBuffer, releaseFence); } -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) status_t BufferItemConsumer::releaseBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& releaseFence) { Mutex::Autolock _l(mMutex); @@ -129,7 +178,6 @@ status_t BufferItemConsumer::releaseBuffer(const sp<GraphicBuffer>& buffer, return releaseBufferSlotLocked(slotIndex, buffer, releaseFence); } -#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) status_t BufferItemConsumer::releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer, const sp<Fence>& releaseFence) { diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index f1374e23fd..f21ac18f3c 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -125,15 +125,16 @@ void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer, LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BufferQueue: outConsumer must not be NULL"); - sp<BufferQueueCore> core(new BufferQueueCore()); + sp<BufferQueueCore> core = sp<BufferQueueCore>::make(); LOG_ALWAYS_FATAL_IF(core == nullptr, "BufferQueue: failed to create BufferQueueCore"); - sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger)); + sp<IGraphicBufferProducer> producer = + sp<BufferQueueProducer>::make(core, consumerIsSurfaceFlinger); LOG_ALWAYS_FATAL_IF(producer == nullptr, "BufferQueue: failed to create BufferQueueProducer"); - sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core)); + sp<IGraphicBufferConsumer> consumer = sp<BufferQueueConsumer>::make(core); LOG_ALWAYS_FATAL_IF(consumer == nullptr, "BufferQueue: failed to create BufferQueueConsumer"); diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index f0125868ae..4681c9ecbe 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -14,10 +14,6 @@ * limitations under the License. */ -#include <inttypes.h> -#include <pwd.h> -#include <sys/types.h> - #define LOG_TAG "BufferQueueConsumer" #define ATRACE_TAG ATRACE_TAG_GRAPHICS //#define LOG_NDEBUG 0 @@ -48,6 +44,11 @@ #include <com_android_graphics_libgui_flags.h> +#include <inttypes.h> +#include <pwd.h> +#include <sys/types.h> +#include <optional> + namespace android { // Macros for include BufferQueueCore information in log messages @@ -477,9 +478,14 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, return NO_ERROR; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) +status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, + const sp<Fence>& releaseFence) { +#else status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence, EGLDisplay eglDisplay, EGLSyncKHR eglFence) { +#endif ATRACE_CALL(); ATRACE_BUFFER_INDEX(slot); @@ -493,27 +499,6 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, return BAD_VALUE; } -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) - if (eglFence != EGL_NO_SYNC_KHR) { - // Most platforms will be using native fences, so it's unlikely that we'll ever have to - // process an eglFence. Ideally we can remove this code eventually. In the mean time, do our - // best to wait for it so the buffer stays valid, otherwise return an error to the caller. - // - // EGL_SYNC_FLUSH_COMMANDS_BIT_KHR so that we don't wait forever on a fence that hasn't - // shown up on the GPU yet. - EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, - 1000000000); - if (result == EGL_FALSE) { - BQ_LOGE("releaseBuffer: error %#x waiting for fence", eglGetError()); - return UNKNOWN_ERROR; - } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { - BQ_LOGE("releaseBuffer: timeout waiting for fence"); - return UNKNOWN_ERROR; - } - eglDestroySyncKHR(eglDisplay, eglFence); - } -#endif - sp<IProducerListener> listener; { // Autolock scope std::lock_guard<std::mutex> lock(mCore->mMutex); @@ -783,11 +768,15 @@ status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { return NO_ERROR; } +status_t BufferQueueConsumer::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { + return setMaxAcquiredBufferCount(maxAcquiredBuffers, std::nullopt); +} + status_t BufferQueueConsumer::setMaxAcquiredBufferCount( - int maxAcquiredBuffers) { + int maxAcquiredBuffers, std::optional<OnBufferReleasedCallback> onBuffersReleasedCallback) { ATRACE_FORMAT("%s(%d)", __func__, maxAcquiredBuffers); - sp<IConsumerListener> listener; + std::optional<OnBufferReleasedCallback> callback; { // Autolock scope std::unique_lock<std::mutex> lock(mCore->mMutex); @@ -849,13 +838,20 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers); mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; VALIDATE_CONSISTENCY(); - if (delta < 0 && mCore->mBufferReleasedCbEnabled) { - listener = mCore->mConsumerListener; + if (delta < 0) { + if (onBuffersReleasedCallback) { + callback = std::move(onBuffersReleasedCallback); + } else if (mCore->mBufferReleasedCbEnabled) { + callback = [listener = mCore->mConsumerListener]() { + listener->onBuffersReleased(); + }; + } } } + // Call back without lock held - if (listener != nullptr) { - listener->onBuffersReleased(); + if (callback) { + (*callback)(); } return NO_ERROR; diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index c241482827..bcf61e45de 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -364,8 +364,10 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller, // Producers are not allowed to dequeue more than // mMaxDequeuedBufferCount buffers. // This check is only done if a buffer has already been queued - if (mCore->mBufferHasBeenQueued && - dequeuedCount >= mCore->mMaxDequeuedBufferCount) { + using namespace com::android::graphics::libgui::flags; + bool flagGatedBufferHasBeenQueued = + bq_always_use_max_dequeued_buffer_count() || mCore->mBufferHasBeenQueued; + if (flagGatedBufferHasBeenQueued && dequeuedCount >= mCore->mMaxDequeuedBufferCount) { // Supress error logs when timeout is non-negative. if (mDequeueTimeout < 0) { BQ_LOGE("%s: attempting to exceed the max dequeued buffer " @@ -693,11 +695,11 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou .requestorName = {mConsumerName.c_str(), mConsumerName.size()}, .extras = std::move(tempOptions), }; - sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(allocRequest); + sp<GraphicBuffer> graphicBuffer = sp<GraphicBuffer>::make(allocRequest); #else sp<GraphicBuffer> graphicBuffer = - new GraphicBuffer(width, height, format, BQ_LAYER_COUNT, usage, - {mConsumerName.c_str(), mConsumerName.size()}); + sp<GraphicBuffer>::make(width, height, format, BQ_LAYER_COUNT, usage, + std::string{mConsumerName.c_str(), mConsumerName.size()}); #endif status_t error = graphicBuffer->initCheck(); @@ -1464,7 +1466,7 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, #ifndef NO_BINDER if (IInterface::asBinder(listener)->remoteBinder() != nullptr) { status = IInterface::asBinder(listener)->linkToDeath( - static_cast<IBinder::DeathRecipient*>(this)); + sp<IBinder::DeathRecipient>::fromExisting(this)); if (status != NO_ERROR) { BQ_LOGE("connect: linkToDeath failed: %s (%d)", strerror(-status), status); @@ -1553,8 +1555,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { IInterface::asBinder(mCore->mLinkedToDeath); // This can fail if we're here because of the death // notification, but we just ignore it - token->unlinkToDeath( - static_cast<IBinder::DeathRecipient*>(this)); + token->unlinkToDeath(static_cast<IBinder::DeathRecipient*>(this)); } #endif mCore->mSharedBufferSlot = @@ -1685,11 +1686,11 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, #endif #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) - sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(allocRequest); + sp<GraphicBuffer> graphicBuffer = sp<GraphicBuffer>::make(allocRequest); #else - sp<GraphicBuffer> graphicBuffer = new GraphicBuffer( - allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT, - allocUsage, allocName); + sp<GraphicBuffer> graphicBuffer = + sp<GraphicBuffer>::make(allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT, + allocUsage, allocName); #endif status_t result = graphicBuffer->initCheck(); diff --git a/libs/gui/BufferReleaseChannel.cpp b/libs/gui/BufferReleaseChannel.cpp index e9cb013baf..4f495d039d 100644 --- a/libs/gui/BufferReleaseChannel.cpp +++ b/libs/gui/BufferReleaseChannel.cpp @@ -108,7 +108,7 @@ status_t BufferReleaseChannel::Message::flatten(void*& buffer, size_t& size, int status_t BufferReleaseChannel::Message::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) { - releaseFence = new Fence(); + releaseFence = sp<Fence>::make(); if (status_t err = releaseFence->unflatten(buffer, size, fds, count); err != OK) { return err; } @@ -344,4 +344,4 @@ status_t BufferReleaseChannel::open(std::string name, return STATUS_OK; } -} // namespace android::gui
\ No newline at end of file +} // namespace android::gui diff --git a/libs/gui/Choreographer.cpp b/libs/gui/Choreographer.cpp index ba50bf83a8..80a35435cb 100644 --- a/libs/gui/Choreographer.cpp +++ b/libs/gui/Choreographer.cpp @@ -20,6 +20,7 @@ #include <gui/Choreographer.h> #include <gui/TraceUtils.h> #include <jni.h> +#include <utils/Looper.h> #undef LOG_TAG #define LOG_TAG "AChoreographer" @@ -69,7 +70,7 @@ namespace android { Choreographer::Context Choreographer::gChoreographers; -static thread_local Choreographer* gChoreographer; +static thread_local sp<Choreographer> gChoreographer; void Choreographer::initJVM(JNIEnv* env) { env->GetJavaVM(&gJni.jvm); @@ -86,14 +87,14 @@ void Choreographer::initJVM(JNIEnv* env) { "()V"); } -Choreographer* Choreographer::getForThread() { +sp<Choreographer> Choreographer::getForThread() { if (gChoreographer == nullptr) { sp<Looper> looper = Looper::getForThread(); if (!looper.get()) { ALOGW("No looper prepared for thread"); return nullptr; } - gChoreographer = new Choreographer(looper); + gChoreographer = sp<Choreographer>::make(looper); status_t result = gChoreographer->initialize(); if (result != OK) { ALOGW("Failed to initialize"); @@ -238,7 +239,7 @@ void Choreographer::scheduleLatestConfigRequest() { // socket should be atomic across processes. DisplayEventReceiver::Event event; event.header = - DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL, + DisplayEventReceiver::Event::Header{DisplayEventType::DISPLAY_EVENT_NULL, PhysicalDisplayId::fromPort(0), systemTime()}; injectEvent(event); } diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index 504509dbec..5b89c6e17e 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -31,6 +31,7 @@ #include <gui/BufferItem.h> #include <gui/BufferQueue.h> #include <gui/ConsumerBase.h> +#include <gui/IConsumerListener.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> @@ -68,8 +69,8 @@ ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool c #endif mAbandoned(false), mConsumer(bufferQueue), - mPrevFinalReleaseFence(Fence::NO_FENCE) { - initialize(controlledByApp); + mPrevFinalReleaseFence(Fence::NO_FENCE), + mIsControlledByApp(controlledByApp) { } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) @@ -79,11 +80,11 @@ ConsumerBase::ConsumerBase(bool controlledByApp, bool consumerIsSurfaceFlinger) mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), #endif mAbandoned(false), - mPrevFinalReleaseFence(Fence::NO_FENCE) { + mPrevFinalReleaseFence(Fence::NO_FENCE), + mIsControlledByApp(controlledByApp) { sp<IGraphicBufferProducer> producer; BufferQueue::createBufferQueue(&producer, &mConsumer, consumerIsSurfaceFlinger); mSurface = sp<Surface>::make(producer, controlledByApp); - initialize(controlledByApp); } ConsumerBase::ConsumerBase(const sp<IGraphicBufferProducer>& producer, @@ -95,24 +96,27 @@ ConsumerBase::ConsumerBase(const sp<IGraphicBufferProducer>& producer, mAbandoned(false), mConsumer(consumer), mSurface(sp<Surface>::make(producer, controlledByApp)), - mPrevFinalReleaseFence(Fence::NO_FENCE) { - initialize(controlledByApp); + mPrevFinalReleaseFence(Fence::NO_FENCE), + mIsControlledByApp(controlledByApp) { } #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) -void ConsumerBase::initialize(bool controlledByApp) { +void ConsumerBase::onFirstRef() { + ConsumerListener::onFirstRef(); + initialize(); +} + +void ConsumerBase::initialize() { // Choose a name using the PID and a process-unique ID. mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); - // Note that we can't create an sp<...>(this) in a ctor that will not keep a - // reference once the ctor ends, as that would cause the refcount of 'this' - // dropping to 0 at the end of the ctor. Since all we need is a wp<...> - // that's what we create. - wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this); - sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener); + // Here we depend on an sp/wp having been created for `this`. For this + // reason, initialize() cannot be called from a ctor. + wp<ConsumerListener> listener = wp<ConsumerListener>::fromExisting(this); + sp<IConsumerListener> proxy = sp<BufferQueue::ProxyConsumerListener>::make(listener); - status_t err = mConsumer->consumerConnect(proxy, controlledByApp); + status_t err = mConsumer->consumerConnect(proxy, mIsControlledByApp); if (err != NO_ERROR) { CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)", strerror(-err), err); @@ -260,7 +264,10 @@ void ConsumerBase::onFrameReplaced(const BufferItem &item) { void ConsumerBase::onBuffersReleased() { Mutex::Autolock lock(mMutex); + onBuffersReleasedLocked(); +} +void ConsumerBase::onBuffersReleasedLocked() { CB_LOGV("onBuffersReleased"); if (mAbandoned) { @@ -385,6 +392,26 @@ status_t ConsumerBase::detachBuffer(const sp<GraphicBuffer>& buffer) { } #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) +status_t ConsumerBase::addReleaseFence(const sp<GraphicBuffer> buffer, const sp<Fence>& fence) { + CB_LOGV("addReleaseFence"); + Mutex::Autolock lock(mMutex); + + if (mAbandoned) { + CB_LOGE("addReleaseFence: ConsumerBase is abandoned!"); + return NO_INIT; + } + if (buffer == nullptr) { + return BAD_VALUE; + } + + int slotIndex = getSlotForBufferLocked(buffer); + if (slotIndex == BufferQueue::INVALID_BUFFER_SLOT) { + return BAD_VALUE; + } + + return addReleaseFenceLocked(slotIndex, buffer, fence); +} + status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) { Mutex::Autolock _l(mMutex); if (mAbandoned) { @@ -457,10 +484,10 @@ status_t ConsumerBase::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { CB_LOGE("setMaxAcquiredBufferCount: ConsumerBase is abandoned!"); return NO_INIT; } - return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers); + return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers, + {[this]() { onBuffersReleasedLocked(); }}); } -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) status_t ConsumerBase::setConsumerIsProtected(bool isProtected) { Mutex::Autolock lock(mMutex); if (mAbandoned) { @@ -469,7 +496,6 @@ status_t ConsumerBase::setConsumerIsProtected(bool isProtected) { } return mConsumer->setConsumerIsProtected(isProtected); } -#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) sp<NativeHandle> ConsumerBase::getSidebandStream() const { Mutex::Autolock _l(mMutex); @@ -656,9 +682,13 @@ status_t ConsumerBase::addReleaseFenceLocked(int slot, return OK; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) +status_t ConsumerBase::releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer) { +#else status_t ConsumerBase::releaseBufferLocked( int slot, const sp<GraphicBuffer> graphicBuffer, EGLDisplay display, EGLSyncKHR eglFence) { +#endif if (mAbandoned) { CB_LOGE("releaseBufferLocked: ConsumerBase is abandoned!"); return NO_INIT; @@ -675,8 +705,12 @@ status_t ConsumerBase::releaseBufferLocked( CB_LOGV("releaseBufferLocked: slot=%d/%" PRIu64, slot, mSlots[slot].mFrameNumber); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber, mSlots[slot].mFence); +#else status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber, display, eglFence, mSlots[slot].mFence); +#endif if (err == IGraphicBufferConsumer::STALE_BUFFER_SLOT) { freeBufferLocked(slot); } diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp index 23b432e1f4..ecbceb7a79 100644 --- a/libs/gui/CpuConsumer.cpp +++ b/libs/gui/CpuConsumer.cpp @@ -20,7 +20,11 @@ #include <com_android_graphics_libgui_flags.h> #include <gui/BufferItem.h> +#include <gui/BufferQueue.h> #include <gui/CpuConsumer.h> +#include <gui/IGraphicBufferConsumer.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/Surface.h> #include <utils/Log.h> #define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__) @@ -31,6 +35,28 @@ namespace android { +std::tuple<sp<CpuConsumer>, sp<Surface>> CpuConsumer::create(size_t maxLockedBuffers, + bool controlledByApp, + bool isConsumerSurfaceFlinger) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) + sp<CpuConsumer> consumer = + sp<CpuConsumer>::make(maxLockedBuffers, controlledByApp, isConsumerSurfaceFlinger); + return {consumer, consumer->getSurface()}; +#else + sp<IGraphicBufferProducer> igbp; + sp<IGraphicBufferConsumer> igbc; + BufferQueue::createBufferQueue(&igbp, &igbc, isConsumerSurfaceFlinger); + + return {sp<CpuConsumer>::make(igbc, maxLockedBuffers, controlledByApp), + sp<Surface>::make(igbp, controlledByApp)}; +#endif +} + +sp<CpuConsumer> CpuConsumer::create(const sp<IGraphicBufferConsumer>& bq, size_t maxLockedBuffers, + bool controlledByApp) { + return sp<CpuConsumer>::make(bq, maxLockedBuffers, controlledByApp); +} + #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) CpuConsumer::CpuConsumer(size_t maxLockedBuffers, bool controlledByApp, bool isConsumerSurfaceFlinger) @@ -230,7 +256,7 @@ status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) { return err; } - sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); + sp<Fence> fence(fenceFd >= 0 ? sp<Fence>::make(fenceFd) : Fence::NO_FENCE); addReleaseFenceLocked(ab.mSlot, ab.mGraphicBuffer, fence); releaseBufferLocked(ab.mSlot, ab.mGraphicBuffer); diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp index 68f10f4d80..6f238859a4 100644 --- a/libs/gui/DisplayEventDispatcher.cpp +++ b/libs/gui/DisplayEventDispatcher.cpp @@ -167,7 +167,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, for (ssize_t i = 0; i < n; i++) { const DisplayEventReceiver::Event& ev = buf[i]; switch (ev.header.type) { - case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: + case DisplayEventType::DISPLAY_EVENT_VSYNC: // Later vsync events will just overwrite the info from earlier // ones. That's fine, we only care about the most recent. gotVsync = true; @@ -183,7 +183,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, ATRACE_INT("RenderRate", fps); } break; - case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: + case DisplayEventType::DISPLAY_EVENT_HOTPLUG: if (ev.hotplug.connectionError == 0) { dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected); @@ -192,31 +192,28 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, ev.hotplug.connectionError); } break; - case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: + case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE: dispatchModeChanged(ev.header.timestamp, ev.header.displayId, ev.modeChange.modeId, ev.modeChange.vsyncPeriod); break; - case DisplayEventReceiver::DISPLAY_EVENT_NULL: + case DisplayEventType::DISPLAY_EVENT_NULL: dispatchNullEvent(ev.header.timestamp, ev.header.displayId); break; - case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE: + case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE: mFrameRateOverrides.emplace_back(ev.frameRateOverride); break; - case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH: + case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH: dispatchFrameRateOverrides(ev.header.timestamp, ev.header.displayId, std::move(mFrameRateOverrides)); break; - case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE: + case DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE: dispatchHdcpLevelsChanged(ev.header.displayId, ev.hdcpLevelsChange.connectedLevel, ev.hdcpLevelsChange.maxLevel); break; - case DisplayEventReceiver::DISPLAY_EVENT_MODE_REJECTION: + case DisplayEventType::DISPLAY_EVENT_MODE_REJECTION: dispatchModeRejected(ev.header.displayId, ev.modeRejection.modeId); break; - default: - ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type); - break; } } } diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index 168129b1f7..2c5770d4c6 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -37,6 +37,7 @@ #include <gui/DebugEGLImageTracker.h> #include <gui/GLConsumer.h> #include <gui/ISurfaceComposer.h> +#include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> #include <private/gui/ComposerService.h> @@ -101,6 +102,50 @@ static bool hasEglProtectedContent() { return hasIt; } +std::tuple<sp<GLConsumer>, sp<Surface>> GLConsumer::create(uint32_t tex, uint32_t textureTarget, + bool useFenceSync, + bool isControlledByApp) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) + sp<GLConsumer> consumer = + sp<GLConsumer>::make(tex, textureTarget, useFenceSync, isControlledByApp); + return {consumer, consumer->getSurface()}; +#else + sp<IGraphicBufferProducer> igbp; + sp<IGraphicBufferConsumer> igbc; + BufferQueue::createBufferQueue(&igbp, &igbc); + + return {sp<GLConsumer>::make(igbc, tex, textureTarget, useFenceSync, isControlledByApp), + sp<Surface>::make(igbp, isControlledByApp)}; +#endif +} + +std::tuple<sp<GLConsumer>, sp<Surface>> GLConsumer::create(uint32_t textureTarget, + bool useFenceSync, + bool isControlledByApp) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) + sp<GLConsumer> consumer = sp<GLConsumer>::make(textureTarget, useFenceSync, isControlledByApp); + return {consumer, consumer->getSurface()}; +#else + sp<IGraphicBufferProducer> igbp; + sp<IGraphicBufferConsumer> igbc; + BufferQueue::createBufferQueue(&igbp, &igbc); + + return {sp<GLConsumer>::make(igbc, textureTarget, useFenceSync, isControlledByApp), + sp<Surface>::make(igbp, isControlledByApp)}; +#endif +} + +sp<GLConsumer> GLConsumer::create(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, + uint32_t textureTarget, bool useFenceSync, + bool isControlledByApp) { + return sp<GLConsumer>::make(bq, tex, textureTarget, useFenceSync, isControlledByApp); +} + +sp<GLConsumer> GLConsumer::create(const sp<IGraphicBufferConsumer>& bq, uint32_t textureTarget, + bool useFenceSync, bool isControlledByApp) { + return sp<GLConsumer>::make(bq, textureTarget, useFenceSync, isControlledByApp); +} + #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) GLConsumer::GLConsumer(uint32_t tex, uint32_t texTarget, bool useFenceSync, bool isControlledByApp) : ConsumerBase(isControlledByApp, /* isConsumerSurfaceFlinger */ false), @@ -333,7 +378,7 @@ status_t GLConsumer::releaseTexImage() { } if (mReleasedTexImage == nullptr) { - mReleasedTexImage = new EglImage(getDebugTexImageBuffer()); + mReleasedTexImage = sp<EglImage>::make(getDebugTexImageBuffer()); } mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; @@ -365,10 +410,10 @@ sp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() { if (CC_UNLIKELY(sReleasedTexImageBuffer == nullptr)) { // The first time, create the debug texture in case the application // continues to use it. - sp<GraphicBuffer> buffer = new GraphicBuffer( - kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888, - DEFAULT_USAGE_FLAGS | GraphicBuffer::USAGE_SW_WRITE_RARELY, - "[GLConsumer debug texture]"); + sp<GraphicBuffer> buffer = + sp<GraphicBuffer>::make(kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888, + DEFAULT_USAGE_FLAGS | GraphicBuffer::USAGE_SW_WRITE_RARELY, + "[GLConsumer debug texture]"); uint32_t* bits; buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits)); uint32_t stride = buffer->getStride(); @@ -400,7 +445,7 @@ status_t GLConsumer::acquireBufferLocked(BufferItem *item, // replaces any old EglImage with a new one (using the new buffer). if (item->mGraphicBuffer != nullptr) { int slot = item->mSlot; - mEglSlots[slot].mEglImage = new EglImage(item->mGraphicBuffer); + mEglSlots[slot].mEglImage = sp<EglImage>::make(item->mGraphicBuffer); } return NO_ERROR; @@ -417,18 +462,18 @@ void GLConsumer::onSlotCountChanged(int slotCount) { } #endif -status_t GLConsumer::releaseBufferLocked(int buf, - sp<GraphicBuffer> graphicBuffer, - EGLDisplay display, EGLSyncKHR eglFence) { +#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) +status_t GLConsumer::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicBuffer, + EGLDisplay display, EGLSyncKHR eglFence) { // release the buffer if it hasn't already been discarded by the // BufferQueue. This can happen, for example, when the producer of this // buffer has reallocated the original buffer slot after this buffer // was acquired. - status_t err = ConsumerBase::releaseBufferLocked( - buf, graphicBuffer, display, eglFence); + status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer, display, eglFence); mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; return err; } +#endif status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, PendingRelease* pendingRelease) @@ -490,9 +535,14 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, // release old buffer if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (pendingRelease == nullptr) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + status_t status = + releaseBufferLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer()); +#else status_t status = releaseBufferLocked( mCurrentTexture, mCurrentTextureImage->graphicBuffer(), mEglDisplay, mEglSlots[mCurrentTexture].mEglFence); +#endif if (status < NO_ERROR) { GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status), status); @@ -501,10 +551,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, } } else { pendingRelease->currentTexture = mCurrentTexture; - pendingRelease->graphicBuffer = - mCurrentTextureImage->graphicBuffer(); - pendingRelease->display = mEglDisplay; - pendingRelease->fence = mEglSlots[mCurrentTexture].mEglFence; + pendingRelease->graphicBuffer = mCurrentTextureImage->graphicBuffer(); pendingRelease->isPending = true; } } @@ -735,7 +782,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { "fd: %#x", eglGetError()); return UNKNOWN_ERROR; } - sp<Fence> fence(new Fence(fenceFd)); + sp<Fence> fence = sp<Fence>::make(fenceFd); status_t err = addReleaseFenceLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer(), fence); if (err != OK) { @@ -744,6 +791,11 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { return err; } } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + // Basically all clients are using native fence syncs. If they aren't, we lose nothing + // by waiting here, because the alternative can cause deadlocks (b/339705065). + glFinish(); +#else EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; if (fence != EGL_NO_SYNC_KHR) { // There is already a fence for the current slot. We need to @@ -773,6 +825,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { } glFlush(); mEglSlots[mCurrentTexture].mEglFence = fence; +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) } } diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp deleted file mode 100644 index 939db594ec..0000000000 --- a/libs/gui/IConsumerListener.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <gui/IConsumerListener.h> - -#include <gui/BufferItem.h> - -namespace android { - -namespace { // Anonymous - -enum class Tag : uint32_t { - ON_DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, - ON_FRAME_AVAILABLE, - ON_FRAME_REPLACED, - ON_BUFFERS_RELEASED, - ON_SIDEBAND_STREAM_CHANGED, - ON_FRAME_DEQUEUED, - ON_FRAME_CANCELLED, - ON_FRAME_DETACHED, - ON_SLOT_COUNT_CHANGED, - LAST = ON_SLOT_COUNT_CHANGED, -}; - -} // Anonymous namespace - -class BpConsumerListener : public SafeBpInterface<IConsumerListener> { -public: - explicit BpConsumerListener(const sp<IBinder>& impl) - : SafeBpInterface<IConsumerListener>(impl, "BpConsumerListener") {} - - ~BpConsumerListener() override; - - void onDisconnect() override { - callRemoteAsync<decltype(&IConsumerListener::onDisconnect)>(Tag::ON_DISCONNECT); - } - - void onFrameDequeued(const uint64_t bufferId) override { - callRemoteAsync<decltype(&IConsumerListener::onFrameDequeued)>(Tag::ON_FRAME_DEQUEUED, - bufferId); - } - - void onFrameDetached(const uint64_t bufferId) override { - callRemoteAsync<decltype(&IConsumerListener::onFrameDetached)>(Tag::ON_FRAME_DETACHED, - bufferId); - } - - void onFrameCancelled(const uint64_t bufferId) override { - callRemoteAsync<decltype(&IConsumerListener::onFrameCancelled)>(Tag::ON_FRAME_CANCELLED, - bufferId); - } - - void onFrameAvailable(const BufferItem& item) override { - callRemoteAsync<decltype(&IConsumerListener::onFrameAvailable)>(Tag::ON_FRAME_AVAILABLE, - item); - } - - void onFrameReplaced(const BufferItem& item) override { - callRemoteAsync<decltype(&IConsumerListener::onFrameReplaced)>(Tag::ON_FRAME_REPLACED, - item); - } - - void onBuffersReleased() override { - callRemoteAsync<decltype(&IConsumerListener::onBuffersReleased)>(Tag::ON_BUFFERS_RELEASED); - } - - void onSidebandStreamChanged() override { - callRemoteAsync<decltype(&IConsumerListener::onSidebandStreamChanged)>( - Tag::ON_SIDEBAND_STREAM_CHANGED); - } - - void addAndGetFrameTimestamps(const NewFrameEventsEntry* /*newTimestamps*/, - FrameEventHistoryDelta* /*outDelta*/) override { - LOG_ALWAYS_FATAL("IConsumerListener::addAndGetFrameTimestamps cannot be proxied"); - } - -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) - void onSlotCountChanged(int slotCount) override { - callRemoteAsync< - decltype(&IConsumerListener::onSlotCountChanged)>(Tag::ON_SLOT_COUNT_CHANGED, - slotCount); - } -#endif -}; - -// Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see -// clang warning -Wweak-vtables) -BpConsumerListener::~BpConsumerListener() = default; - -IMPLEMENT_META_INTERFACE(ConsumerListener, "android.gui.IConsumerListener"); - -status_t BnConsumerListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags) { - if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) { - return BBinder::onTransact(code, data, reply, flags); - } - auto tag = static_cast<Tag>(code); - switch (tag) { - case Tag::ON_DISCONNECT: - return callLocalAsync(data, reply, &IConsumerListener::onDisconnect); - case Tag::ON_FRAME_AVAILABLE: - return callLocalAsync(data, reply, &IConsumerListener::onFrameAvailable); - case Tag::ON_FRAME_REPLACED: - return callLocalAsync(data, reply, &IConsumerListener::onFrameReplaced); - case Tag::ON_BUFFERS_RELEASED: - return callLocalAsync(data, reply, &IConsumerListener::onBuffersReleased); - case Tag::ON_SIDEBAND_STREAM_CHANGED: - return callLocalAsync(data, reply, &IConsumerListener::onSidebandStreamChanged); - case Tag::ON_FRAME_DEQUEUED: - return callLocalAsync(data, reply, &IConsumerListener::onFrameDequeued); - case Tag::ON_FRAME_CANCELLED: - return callLocalAsync(data, reply, &IConsumerListener::onFrameCancelled); - case Tag::ON_FRAME_DETACHED: - return callLocalAsync(data, reply, &IConsumerListener::onFrameDetached); - case Tag::ON_SLOT_COUNT_CHANGED: { -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) - return callLocalAsync(data, reply, &IConsumerListener::onSlotCountChanged); -#else - return INVALID_OPERATION; -#endif - } - } -} - -} // namespace android diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp deleted file mode 100644 index c1b65689d6..0000000000 --- a/libs/gui/IGraphicBufferConsumer.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <gui/IGraphicBufferConsumer.h> - -#include <com_android_graphics_libgui_flags.h> -#include <gui/BufferItem.h> -#include <gui/IConsumerListener.h> - -#include <binder/Parcel.h> - -#include <ui/Fence.h> -#include <ui/GraphicBuffer.h> - -#include <utils/Errors.h> -#include <utils/NativeHandle.h> -#include <utils/String8.h> -#include <cstdint> - -namespace android { - -namespace { // Anonymous namespace - -enum class Tag : uint32_t { - ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION, - DETACH_BUFFER, - ATTACH_BUFFER, - RELEASE_BUFFER, - CONSUMER_CONNECT, - CONSUMER_DISCONNECT, - GET_RELEASED_BUFFERS, - SET_DEFAULT_BUFFER_SIZE, - SET_MAX_BUFFER_COUNT, - SET_MAX_ACQUIRED_BUFFER_COUNT, - SET_CONSUMER_NAME, - SET_DEFAULT_BUFFER_FORMAT, - SET_DEFAULT_BUFFER_DATA_SPACE, - SET_CONSUMER_USAGE_BITS, - SET_CONSUMER_IS_PROTECTED, - SET_TRANSFORM_HINT, - GET_SIDEBAND_STREAM, - GET_OCCUPANCY_HISTORY, - DISCARD_FREE_BUFFERS, - DUMP_STATE, - ALLOW_UNLIMITED_SLOTS, - GET_RELEASED_BUFFERS_EXTENDED, - LAST = GET_RELEASED_BUFFERS_EXTENDED, -}; - -} // Anonymous namespace - -class BpGraphicBufferConsumer : public SafeBpInterface<IGraphicBufferConsumer> { -public: - explicit BpGraphicBufferConsumer(const sp<IBinder>& impl) - : SafeBpInterface<IGraphicBufferConsumer>(impl, "BpGraphicBufferConsumer") {} - - ~BpGraphicBufferConsumer() override; - - status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen, - uint64_t maxFrameNumber) override { - using Signature = decltype(&IGraphicBufferConsumer::acquireBuffer); - return callRemote<Signature>(Tag::ACQUIRE_BUFFER, buffer, presentWhen, maxFrameNumber); - } - - status_t detachBuffer(int slot) override { - using Signature = decltype(&IGraphicBufferConsumer::detachBuffer); - return callRemote<Signature>(Tag::DETACH_BUFFER, slot); - } - - status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) override { - using Signature = decltype(&IGraphicBufferConsumer::attachBuffer); - return callRemote<Signature>(Tag::ATTACH_BUFFER, slot, buffer); - } - - status_t releaseBuffer(int buf, uint64_t frameNumber, - EGLDisplay display __attribute__((unused)), - EGLSyncKHR fence __attribute__((unused)), - const sp<Fence>& releaseFence) override { - using Signature = status_t (IGraphicBufferConsumer::*)(int, uint64_t, const sp<Fence>&); - return callRemote<Signature>(Tag::RELEASE_BUFFER, buf, frameNumber, releaseFence); - } - - status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) override { - using Signature = decltype(&IGraphicBufferConsumer::consumerConnect); - return callRemote<Signature>(Tag::CONSUMER_CONNECT, consumer, controlledByApp); - } - - status_t consumerDisconnect() override { - return callRemote<decltype(&IGraphicBufferConsumer::consumerDisconnect)>( - Tag::CONSUMER_DISCONNECT); - } - - status_t getReleasedBuffers(uint64_t* slotMask) override { - using Signature = decltype(&IGraphicBufferConsumer::getReleasedBuffers); - return callRemote<Signature>(Tag::GET_RELEASED_BUFFERS, slotMask); - } - -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) - status_t getReleasedBuffersExtended(std::vector<bool>* slotMask) override { - using Signature = decltype(&IGraphicBufferConsumer::getReleasedBuffersExtended); - return callRemote<Signature>(Tag::GET_RELEASED_BUFFERS_EXTENDED, slotMask); - } -#endif - - status_t setDefaultBufferSize(uint32_t width, uint32_t height) override { - using Signature = decltype(&IGraphicBufferConsumer::setDefaultBufferSize); - return callRemote<Signature>(Tag::SET_DEFAULT_BUFFER_SIZE, width, height); - } - -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) - status_t allowUnlimitedSlots(bool allowUnlimitedSlots) override { - using Signature = decltype(&IGraphicBufferConsumer::allowUnlimitedSlots); - return callRemote<Signature>(Tag::ALLOW_UNLIMITED_SLOTS, allowUnlimitedSlots); - } -#endif - - status_t setMaxBufferCount(int bufferCount) override { - using Signature = decltype(&IGraphicBufferConsumer::setMaxBufferCount); - return callRemote<Signature>(Tag::SET_MAX_BUFFER_COUNT, bufferCount); - } - - status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) override { - using Signature = decltype(&IGraphicBufferConsumer::setMaxAcquiredBufferCount); - return callRemote<Signature>(Tag::SET_MAX_ACQUIRED_BUFFER_COUNT, maxAcquiredBuffers); - } - - status_t setConsumerName(const String8& name) override { - using Signature = decltype(&IGraphicBufferConsumer::setConsumerName); - return callRemote<Signature>(Tag::SET_CONSUMER_NAME, name); - } - - status_t setDefaultBufferFormat(PixelFormat defaultFormat) override { - using Signature = decltype(&IGraphicBufferConsumer::setDefaultBufferFormat); - return callRemote<Signature>(Tag::SET_DEFAULT_BUFFER_FORMAT, defaultFormat); - } - - status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace) override { - using Signature = decltype(&IGraphicBufferConsumer::setDefaultBufferDataSpace); - return callRemote<Signature>(Tag::SET_DEFAULT_BUFFER_DATA_SPACE, defaultDataSpace); - } - - status_t setConsumerUsageBits(uint64_t usage) override { - using Signature = decltype(&IGraphicBufferConsumer::setConsumerUsageBits); - return callRemote<Signature>(Tag::SET_CONSUMER_USAGE_BITS, usage); - } - - status_t setConsumerIsProtected(bool isProtected) override { - using Signature = decltype(&IGraphicBufferConsumer::setConsumerIsProtected); - return callRemote<Signature>(Tag::SET_CONSUMER_IS_PROTECTED, isProtected); - } - - status_t setTransformHint(uint32_t hint) override { - using Signature = decltype(&IGraphicBufferConsumer::setTransformHint); - return callRemote<Signature>(Tag::SET_TRANSFORM_HINT, hint); - } - - status_t getSidebandStream(sp<NativeHandle>* outStream) const override { - using Signature = decltype(&IGraphicBufferConsumer::getSidebandStream); - return callRemote<Signature>(Tag::GET_SIDEBAND_STREAM, outStream); - } - - status_t getOccupancyHistory(bool forceFlush, - std::vector<OccupancyTracker::Segment>* outHistory) override { - using Signature = decltype(&IGraphicBufferConsumer::getOccupancyHistory); - return callRemote<Signature>(Tag::GET_OCCUPANCY_HISTORY, forceFlush, outHistory); - } - - status_t discardFreeBuffers() override { - return callRemote<decltype(&IGraphicBufferConsumer::discardFreeBuffers)>( - Tag::DISCARD_FREE_BUFFERS); - } - - status_t dumpState(const String8& prefix, String8* outResult) const override { - using Signature = status_t (IGraphicBufferConsumer::*)(const String8&, String8*) const; - return callRemote<Signature>(Tag::DUMP_STATE, prefix, outResult); - } -}; - -// Out-of-line virtual method definition to trigger vtable emission in this translation unit -// (see clang warning -Wweak-vtables) -BpGraphicBufferConsumer::~BpGraphicBufferConsumer() = default; - -IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer"); - -status_t BnGraphicBufferConsumer::onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags) { - if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) { - return BBinder::onTransact(code, data, reply, flags); - } - auto tag = static_cast<Tag>(code); - switch (tag) { - case Tag::ACQUIRE_BUFFER: - return callLocal(data, reply, &IGraphicBufferConsumer::acquireBuffer); - case Tag::DETACH_BUFFER: - return callLocal(data, reply, &IGraphicBufferConsumer::detachBuffer); - case Tag::ATTACH_BUFFER: - return callLocal(data, reply, &IGraphicBufferConsumer::attachBuffer); - case Tag::RELEASE_BUFFER: { - using Signature = status_t (IGraphicBufferConsumer::*)(int, uint64_t, const sp<Fence>&); - return callLocal<Signature>(data, reply, &IGraphicBufferConsumer::releaseBuffer); - } - case Tag::CONSUMER_CONNECT: - return callLocal(data, reply, &IGraphicBufferConsumer::consumerConnect); - case Tag::CONSUMER_DISCONNECT: - return callLocal(data, reply, &IGraphicBufferConsumer::consumerDisconnect); - case Tag::GET_RELEASED_BUFFERS: - return callLocal(data, reply, &IGraphicBufferConsumer::getReleasedBuffers); - case Tag::SET_DEFAULT_BUFFER_SIZE: - return callLocal(data, reply, &IGraphicBufferConsumer::setDefaultBufferSize); - case Tag::SET_MAX_BUFFER_COUNT: - return callLocal(data, reply, &IGraphicBufferConsumer::setMaxBufferCount); - case Tag::SET_MAX_ACQUIRED_BUFFER_COUNT: - return callLocal(data, reply, &IGraphicBufferConsumer::setMaxAcquiredBufferCount); - case Tag::SET_CONSUMER_NAME: - return callLocal(data, reply, &IGraphicBufferConsumer::setConsumerName); - case Tag::SET_DEFAULT_BUFFER_FORMAT: - return callLocal(data, reply, &IGraphicBufferConsumer::setDefaultBufferFormat); - case Tag::SET_DEFAULT_BUFFER_DATA_SPACE: - return callLocal(data, reply, &IGraphicBufferConsumer::setDefaultBufferDataSpace); - case Tag::SET_CONSUMER_USAGE_BITS: - return callLocal(data, reply, &IGraphicBufferConsumer::setConsumerUsageBits); - case Tag::SET_CONSUMER_IS_PROTECTED: - return callLocal(data, reply, &IGraphicBufferConsumer::setConsumerIsProtected); - case Tag::SET_TRANSFORM_HINT: - return callLocal(data, reply, &IGraphicBufferConsumer::setTransformHint); - case Tag::GET_SIDEBAND_STREAM: - return callLocal(data, reply, &IGraphicBufferConsumer::getSidebandStream); - case Tag::GET_OCCUPANCY_HISTORY: - return callLocal(data, reply, &IGraphicBufferConsumer::getOccupancyHistory); - case Tag::DISCARD_FREE_BUFFERS: - return callLocal(data, reply, &IGraphicBufferConsumer::discardFreeBuffers); - case Tag::DUMP_STATE: { - using Signature = status_t (IGraphicBufferConsumer::*)(const String8&, String8*) const; - return callLocal<Signature>(data, reply, &IGraphicBufferConsumer::dumpState); - } - case Tag::GET_RELEASED_BUFFERS_EXTENDED: { -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) - return callLocal(data, reply, &IGraphicBufferConsumer::getReleasedBuffersExtended); -#else - return INVALID_OPERATION; -#endif - } - case Tag::ALLOW_UNLIMITED_SLOTS: { -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) - return callLocal(data, reply, &IGraphicBufferConsumer::allowUnlimitedSlots); -#else - return INVALID_OPERATION; -#endif - } - } -} - -} // namespace android diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 9f71eb16e7..1d1910eb08 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -104,7 +104,7 @@ public: } bool nonNull = reply.readInt32(); if (nonNull) { - *buf = new GraphicBuffer(); + *buf = sp<GraphicBuffer>::make(); result = reply.read(**buf); if(result != NO_ERROR) { (*buf).clear(); @@ -197,7 +197,7 @@ public: } *buf = reply.readInt32(); - *fence = new Fence(); + *fence = sp<Fence>::make(); result = reply.read(**fence); if (result != NO_ERROR) { fence->clear(); @@ -293,7 +293,7 @@ public: if (result == NO_ERROR) { bool nonNull = reply.readInt32(); if (nonNull) { - *outBuffer = new GraphicBuffer; + *outBuffer = sp<GraphicBuffer>::make(); result = reply.read(**outBuffer); if (result != NO_ERROR) { outBuffer->clear(); @@ -302,7 +302,7 @@ public: } nonNull = reply.readInt32(); if (nonNull) { - *outFence = new Fence; + *outFence = sp<Fence>::make(); result = reply.read(**outFence); if (result != NO_ERROR) { outBuffer->clear(); @@ -640,7 +640,7 @@ public: bool hasBuffer = reply.readBool(); sp<GraphicBuffer> buffer; if (hasBuffer) { - buffer = new GraphicBuffer(); + buffer = sp<GraphicBuffer>::make(); result = reply.read(*buffer); if (result == NO_ERROR) { result = reply.read(outTransformMatrix, sizeof(float) * 16); @@ -650,7 +650,7 @@ public: ALOGE("getLastQueuedBuffer failed to read buffer: %d", result); return result; } - sp<Fence> fence(new Fence); + sp<Fence> fence = sp<Fence>::make(); result = reply.read(*fence); if (result != NO_ERROR) { ALOGE("getLastQueuedBuffer failed to read fence: %d", result); @@ -687,7 +687,7 @@ public: } sp<GraphicBuffer> buffer; if (hasBuffer) { - buffer = new GraphicBuffer(); + buffer = sp<GraphicBuffer>::make(); result = reply.read(*buffer); if (result == NO_ERROR) { result = reply.read(*outRect); @@ -700,7 +700,7 @@ public: ALOGE("getLastQueuedBuffer failed to read buffer: %d", result); return result; } - sp<Fence> fence(new Fence); + sp<Fence> fence = sp<Fence>::make(); result = reply.read(*fence); if (result != NO_ERROR) { ALOGE("getLastQueuedBuffer failed to read fence: %d", result); @@ -1232,7 +1232,7 @@ status_t BnGraphicBufferProducer::onTransact( } case ATTACH_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); - sp<GraphicBuffer> buffer = new GraphicBuffer(); + sp<GraphicBuffer> buffer = sp<GraphicBuffer>::make(); status_t result = data.read(*buffer.get()); int slot = 0; if (result == NO_ERROR) { @@ -1250,7 +1250,7 @@ status_t BnGraphicBufferProducer::onTransact( return result; } for (sp<GraphicBuffer>& buffer : buffers) { - buffer = new GraphicBuffer(); + buffer = sp<GraphicBuffer>::make(); result = data.read(*buffer.get()); if (result != NO_ERROR) { return result; @@ -1306,7 +1306,7 @@ status_t BnGraphicBufferProducer::onTransact( case CANCEL_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); int buf = data.readInt32(); - sp<Fence> fence = new Fence(); + sp<Fence> fence = sp<Fence>::make(); status_t result = data.read(*fence.get()); if (result == NO_ERROR) { result = cancelBuffer(buf, fence); diff --git a/libs/gui/IGraphicBufferProducerFlattenables.cpp b/libs/gui/IGraphicBufferProducerFlattenables.cpp index 8b2e2ddc59..393e1c3068 100644 --- a/libs/gui/IGraphicBufferProducerFlattenables.cpp +++ b/libs/gui/IGraphicBufferProducerFlattenables.cpp @@ -105,7 +105,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten( : std::nullopt; #endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES - fence = new Fence(); + fence = sp<Fence>::make(); status_t result = fence->unflatten(buffer, size, fds, count); if (result != NO_ERROR) { return result; @@ -228,7 +228,7 @@ status_t IGraphicBufferProducer::RequestBufferOutput::unflatten( FlattenableUtils::read(fBuffer, size, result); int32_t isBufferNull = 0; FlattenableUtils::read(fBuffer, size, isBufferNull); - buffer = new GraphicBuffer(); + buffer = sp<GraphicBuffer>::make(); if (!isBufferNull) { status_t status = buffer->unflatten(fBuffer, size, fds, count); if (status != NO_ERROR) { @@ -323,7 +323,7 @@ status_t IGraphicBufferProducer::DequeueBufferOutput::unflatten( FlattenableUtils::read(buffer, size, slot); FlattenableUtils::read(buffer, size, bufferAge); - fence = new Fence(); + fence = sp<Fence>::make(); status_t status = fence->unflatten(buffer, size, fds, count); if (status != NO_ERROR) { return status; @@ -395,7 +395,7 @@ status_t IGraphicBufferProducer::CancelBufferInput::unflatten( FlattenableUtils::read(buffer, size, slot); - fence = new Fence(); + fence = sp<Fence>::make(); return fence->unflatten(buffer, size, fds, count); } diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 269936858a..ae4b74e03b 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -26,6 +26,7 @@ #include <gui/ISurfaceComposer.h> #include <gui/LayerState.h> #include <gui/SchedulingPolicy.h> +#include <gui/TransactionState.h> #include <private/gui/ParcelUtils.h> #include <stdint.h> #include <sys/types.h> @@ -60,54 +61,12 @@ public: virtual ~BpSurfaceComposer(); - status_t setTransactionState( - const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, - Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - InputWindowCommands commands, int64_t desiredPresentTime, bool isAutoTimestamp, - const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, - const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId, - const std::vector<uint64_t>& mergedTransactionIds) override { + status_t setTransactionState(TransactionState&& state) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + SAFE_PARCEL(state.writeToParcel, &data); - frameTimelineInfo.writeToParcel(&data); - - SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(state.size())); - for (const auto& s : state) { - SAFE_PARCEL(s.write, data); - } - - SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(displays.size())); - for (const auto& d : displays) { - SAFE_PARCEL(d.write, data); - } - - SAFE_PARCEL(data.writeUint32, flags); - SAFE_PARCEL(data.writeStrongBinder, applyToken); - SAFE_PARCEL(commands.write, data); - SAFE_PARCEL(data.writeInt64, desiredPresentTime); - SAFE_PARCEL(data.writeBool, isAutoTimestamp); - SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(uncacheBuffers.size())); - for (const client_cache_t& uncacheBuffer : uncacheBuffers) { - SAFE_PARCEL(data.writeStrongBinder, uncacheBuffer.token.promote()); - SAFE_PARCEL(data.writeUint64, uncacheBuffer.id); - } - SAFE_PARCEL(data.writeBool, hasListenerCallbacks); - - SAFE_PARCEL(data.writeVectorSize, listenerCallbacks); - for (const auto& [listener, callbackIds] : listenerCallbacks) { - SAFE_PARCEL(data.writeStrongBinder, listener); - SAFE_PARCEL(data.writeParcelableVector, callbackIds); - } - - SAFE_PARCEL(data.writeUint64, transactionId); - - SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(mergedTransactionIds.size())); - for (auto mergedTransactionId : mergedTransactionIds) { - SAFE_PARCEL(data.writeUint64, mergedTransactionId); - } - - if (flags & ISurfaceComposer::eOneWay) { + if (state.mFlags & ISurfaceComposer::eOneWay) { return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply, IBinder::FLAG_ONEWAY); } else { @@ -132,75 +91,9 @@ status_t BnSurfaceComposer::onTransact( case SET_TRANSACTION_STATE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); - FrameTimelineInfo frameTimelineInfo; - frameTimelineInfo.readFromParcel(&data); - - uint32_t count = 0; - SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize()); - Vector<ComposerState> state; - state.setCapacity(count); - for (size_t i = 0; i < count; i++) { - ComposerState s; - SAFE_PARCEL(s.read, data); - state.add(s); - } - - SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize()); - DisplayState d; - Vector<DisplayState> displays; - displays.setCapacity(count); - for (size_t i = 0; i < count; i++) { - SAFE_PARCEL(d.read, data); - displays.add(d); - } - - uint32_t stateFlags = 0; - SAFE_PARCEL(data.readUint32, &stateFlags); - sp<IBinder> applyToken; - SAFE_PARCEL(data.readStrongBinder, &applyToken); - InputWindowCommands inputWindowCommands; - SAFE_PARCEL(inputWindowCommands.read, data); - - int64_t desiredPresentTime = 0; - bool isAutoTimestamp = true; - SAFE_PARCEL(data.readInt64, &desiredPresentTime); - SAFE_PARCEL(data.readBool, &isAutoTimestamp); - - SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize()); - std::vector<client_cache_t> uncacheBuffers(count); - sp<IBinder> tmpBinder; - for (size_t i = 0; i < count; i++) { - SAFE_PARCEL(data.readNullableStrongBinder, &tmpBinder); - uncacheBuffers[i].token = tmpBinder; - SAFE_PARCEL(data.readUint64, &uncacheBuffers[i].id); - } - - bool hasListenerCallbacks = false; - SAFE_PARCEL(data.readBool, &hasListenerCallbacks); - - std::vector<ListenerCallbacks> listenerCallbacks; - int32_t listenersSize = 0; - SAFE_PARCEL_READ_SIZE(data.readInt32, &listenersSize, data.dataSize()); - for (int32_t i = 0; i < listenersSize; i++) { - SAFE_PARCEL(data.readStrongBinder, &tmpBinder); - std::vector<CallbackId> callbackIds; - SAFE_PARCEL(data.readParcelableVector, &callbackIds); - listenerCallbacks.emplace_back(tmpBinder, callbackIds); - } - - uint64_t transactionId = -1; - SAFE_PARCEL(data.readUint64, &transactionId); - - SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize()); - std::vector<uint64_t> mergedTransactions(count); - for (size_t i = 0; i < count; i++) { - SAFE_PARCEL(data.readUint64, &mergedTransactions[i]); - } - - return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken, - std::move(inputWindowCommands), desiredPresentTime, - isAutoTimestamp, uncacheBuffers, hasListenerCallbacks, - listenerCallbacks, transactionId, mergedTransactions); + TransactionState state; + SAFE_PARCEL(state.readFromParcel, &data); + return setTransactionState(std::move(state)); } case GET_SCHEDULING_POLICY: { gui::SchedulingPolicy policy; diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp index 83fc827c5f..ed28e7960b 100644 --- a/libs/gui/ITransactionCompletedListener.cpp +++ b/libs/gui/ITransactionCompletedListener.cpp @@ -92,7 +92,7 @@ status_t FrameEventHistoryStats::readFromParcel(const Parcel* input) { if (err != NO_ERROR) return err; if (hasFence) { - gpuCompositionDoneFence = new Fence(); + gpuCompositionDoneFence = sp<Fence>::make(); err = input->read(*gpuCompositionDoneFence); if (err != NO_ERROR) return err; } @@ -157,7 +157,7 @@ status_t SurfaceStats::readFromParcel(const Parcel* input) { SAFE_PARCEL(input->readBool, &hasFence); if (hasFence) { - previousReleaseFence = new Fence(); + previousReleaseFence = sp<Fence>::make(); SAFE_PARCEL(input->read, *previousReleaseFence); } bool hasTransformHint = false; @@ -216,7 +216,7 @@ status_t TransactionStats::readFromParcel(const Parcel* input) { return err; } if (hasFence) { - presentFence = new Fence(); + presentFence = sp<Fence>::make(); err = input->read(*presentFence); if (err != NO_ERROR) { return err; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index c1a03fcfea..ad95d1a85a 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -55,6 +55,28 @@ namespace android { using gui::FocusRequest; using gui::WindowInfoHandle; +namespace { +bool isSameWindowHandle(const sp<WindowInfoHandle>& lhs, const sp<WindowInfoHandle>& rhs) { + if (lhs == rhs) { + return true; + } + + if (!lhs || !rhs) { + return false; + } + + return *lhs->getInfo() == *rhs->getInfo(); +}; + +bool isSameSurfaceControl(const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) { + if (lhs == rhs) { + return true; + } + + return SurfaceControl::isSameSurface(lhs, rhs); +}; +} // namespace + layer_state_t::layer_state_t() : surface(nullptr), layerId(-1), @@ -66,13 +88,13 @@ layer_state_t::layer_state_t() mask(0), reserved(0), cornerRadius(0.0f), + clientDrawnCornerRadius(0.0f), backgroundBlurRadius(0), color(0), bufferTransform(0), transformToDisplayInverse(false), crop({0, 0, -1, -1}), dataspace(ui::Dataspace::UNKNOWN), - surfaceDamageRegion(), api(-1), colorTransform(mat4()), bgColor(0), @@ -116,19 +138,21 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeFloat, crop.left); SAFE_PARCEL(output.writeFloat, crop.bottom); SAFE_PARCEL(output.writeFloat, crop.right); - SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, relativeLayerSurfaceControl); - SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, parentSurfaceControlForChild); + SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, + mNotDefCmpState.relativeLayerSurfaceControl); + SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, + mNotDefCmpState.parentSurfaceControlForChild); SAFE_PARCEL(output.writeFloat, color.r); SAFE_PARCEL(output.writeFloat, color.g); SAFE_PARCEL(output.writeFloat, color.b); SAFE_PARCEL(output.writeFloat, color.a); - SAFE_PARCEL(windowInfoHandle->writeToParcel, &output); - SAFE_PARCEL(output.write, transparentRegion); + SAFE_PARCEL(mNotDefCmpState.windowInfoHandle->writeToParcel, &output); + SAFE_PARCEL(output.write, mNotDefCmpState.transparentRegion); SAFE_PARCEL(output.writeUint32, bufferTransform); SAFE_PARCEL(output.writeBool, transformToDisplayInverse); SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dataspace)); SAFE_PARCEL(output.write, hdrMetadata); - SAFE_PARCEL(output.write, surfaceDamageRegion); + SAFE_PARCEL(output.write, mNotDefCmpState.surfaceDamageRegion); SAFE_PARCEL(output.writeInt32, api); if (sidebandStream) { @@ -140,6 +164,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.write, colorTransform.asArray(), 16 * sizeof(float)); SAFE_PARCEL(output.writeFloat, cornerRadius); + SAFE_PARCEL(output.writeFloat, clientDrawnCornerRadius); SAFE_PARCEL(output.writeUint32, backgroundBlurRadius); SAFE_PARCEL(output.writeParcelable, metadata); SAFE_PARCEL(output.writeFloat, bgColor.r); @@ -239,8 +264,10 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readFloat, &crop.bottom); SAFE_PARCEL(input.readFloat, &crop.right); - SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &relativeLayerSurfaceControl); - SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &parentSurfaceControlForChild); + SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, + &mNotDefCmpState.relativeLayerSurfaceControl); + SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, + &mNotDefCmpState.parentSurfaceControlForChild); float tmpFloat = 0; SAFE_PARCEL(input.readFloat, &tmpFloat); @@ -252,9 +279,9 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readFloat, &tmpFloat); color.a = tmpFloat; - SAFE_PARCEL(windowInfoHandle->readFromParcel, &input); + SAFE_PARCEL(mNotDefCmpState.windowInfoHandle->readFromParcel, &input); - SAFE_PARCEL(input.read, transparentRegion); + SAFE_PARCEL(input.read, mNotDefCmpState.transparentRegion); SAFE_PARCEL(input.readUint32, &bufferTransform); SAFE_PARCEL(input.readBool, &transformToDisplayInverse); @@ -263,7 +290,7 @@ status_t layer_state_t::read(const Parcel& input) dataspace = static_cast<ui::Dataspace>(tmpUint32); SAFE_PARCEL(input.read, hdrMetadata); - SAFE_PARCEL(input.read, surfaceDamageRegion); + SAFE_PARCEL(input.read, mNotDefCmpState.surfaceDamageRegion); SAFE_PARCEL(input.readInt32, &api); bool tmpBool = false; @@ -274,6 +301,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.read, &colorTransform, 16 * sizeof(float)); SAFE_PARCEL(input.readFloat, &cornerRadius); + SAFE_PARCEL(input.readFloat, &clientDrawnCornerRadius); SAFE_PARCEL(input.readUint32, &backgroundBlurRadius); SAFE_PARCEL(input.readParcelable, &metadata); @@ -580,7 +608,7 @@ void layer_state_t::merge(const layer_state_t& other) { } if (other.what & eTransparentRegionChanged) { what |= eTransparentRegionChanged; - transparentRegion = other.transparentRegion; + mNotDefCmpState.transparentRegion = other.mNotDefCmpState.transparentRegion; } if (other.what & eFlagsChanged) { what |= eFlagsChanged; @@ -596,6 +624,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eCornerRadiusChanged; cornerRadius = other.cornerRadius; } + if (other.what & eClientDrawnCornerRadiusChanged) { + what |= eClientDrawnCornerRadiusChanged; + clientDrawnCornerRadius = other.clientDrawnCornerRadius; + } if (other.what & eBackgroundBlurRadiusChanged) { what |= eBackgroundBlurRadiusChanged; backgroundBlurRadius = other.backgroundBlurRadius; @@ -608,11 +640,13 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eRelativeLayerChanged; what &= ~eLayerChanged; z = other.z; - relativeLayerSurfaceControl = other.relativeLayerSurfaceControl; + mNotDefCmpState.relativeLayerSurfaceControl = + other.mNotDefCmpState.relativeLayerSurfaceControl; } if (other.what & eReparent) { what |= eReparent; - parentSurfaceControlForChild = other.parentSurfaceControlForChild; + mNotDefCmpState.parentSurfaceControlForChild = + other.mNotDefCmpState.parentSurfaceControlForChild; } if (other.what & eBufferTransformChanged) { what |= eBufferTransformChanged; @@ -658,7 +692,7 @@ void layer_state_t::merge(const layer_state_t& other) { } if (other.what & eSurfaceDamageRegionChanged) { what |= eSurfaceDamageRegionChanged; - surfaceDamageRegion = other.surfaceDamageRegion; + mNotDefCmpState.surfaceDamageRegion = other.mNotDefCmpState.surfaceDamageRegion; } if (other.what & eApiChanged) { what |= eApiChanged; @@ -677,7 +711,8 @@ void layer_state_t::merge(const layer_state_t& other) { } if (other.what & eInputInfoChanged) { what |= eInputInfoChanged; - windowInfoHandle = new WindowInfoHandle(*other.windowInfoHandle); + mNotDefCmpState.windowInfoHandle = + sp<WindowInfoHandle>::make(*other.mNotDefCmpState.windowInfoHandle); } if (other.what & eBackgroundColorChanged) { what |= eBackgroundColorChanged; @@ -800,7 +835,8 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const { CHECK_DIFF(diff, eAlphaChanged, other, color.a); CHECK_DIFF(diff, eMatrixChanged, other, matrix); if (other.what & eTransparentRegionChanged && - (!transparentRegion.hasSameRects(other.transparentRegion))) { + (!mNotDefCmpState.transparentRegion.hasSameRects( + other.mNotDefCmpState.transparentRegion))) { diff |= eTransparentRegionChanged; } if (other.what & eFlagsChanged) { @@ -809,6 +845,7 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const { } CHECK_DIFF(diff, eLayerStackChanged, other, layerStack); CHECK_DIFF(diff, eCornerRadiusChanged, other, cornerRadius); + CHECK_DIFF(diff, eClientDrawnCornerRadiusChanged, other, clientDrawnCornerRadius); CHECK_DIFF(diff, eBackgroundBlurRadiusChanged, other, backgroundBlurRadius); if (other.what & eBlurRegionsChanged) diff |= eBlurRegionsChanged; if (other.what & eRelativeLayerChanged) { @@ -816,8 +853,8 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const { diff &= ~eLayerChanged; } if (other.what & eReparent && - !SurfaceControl::isSameSurface(parentSurfaceControlForChild, - other.parentSurfaceControlForChild)) { + !SurfaceControl::isSameSurface(mNotDefCmpState.parentSurfaceControlForChild, + other.mNotDefCmpState.parentSurfaceControlForChild)) { diff |= eReparent; } CHECK_DIFF(diff, eBufferTransformChanged, other, bufferTransform); @@ -831,7 +868,8 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const { CHECK_DIFF(diff, eCachingHintChanged, other, cachingHint); CHECK_DIFF(diff, eHdrMetadataChanged, other, hdrMetadata); if (other.what & eSurfaceDamageRegionChanged && - (!surfaceDamageRegion.hasSameRects(other.surfaceDamageRegion))) { + (!mNotDefCmpState.surfaceDamageRegion.hasSameRects( + other.mNotDefCmpState.surfaceDamageRegion))) { diff |= eSurfaceDamageRegionChanged; } CHECK_DIFF(diff, eApiChanged, other, api); @@ -893,6 +931,38 @@ status_t layer_state_t::matrix22_t::read(const Parcel& input) { SAFE_PARCEL(input.readFloat, &dsdy); return NO_ERROR; } +void layer_state_t::updateTransparentRegion(const Region& transparentRegion) { + what |= eTransparentRegionChanged; + mNotDefCmpState.transparentRegion = transparentRegion; +} +void layer_state_t::updateSurfaceDamageRegion(const Region& surfaceDamageRegion) { + what |= eSurfaceDamageRegionChanged; + mNotDefCmpState.surfaceDamageRegion = surfaceDamageRegion; +} +void layer_state_t::updateRelativeLayer(const sp<SurfaceControl>& relativeTo, int32_t z) { + what |= layer_state_t::eRelativeLayerChanged; + what &= ~layer_state_t::eLayerChanged; + mNotDefCmpState.relativeLayerSurfaceControl = relativeTo; + this->z = z; +} +void layer_state_t::updateParentLayer(const sp<SurfaceControl>& newParent) { + what |= layer_state_t::eReparent; + mNotDefCmpState.parentSurfaceControlForChild = + newParent ? newParent->getParentingLayer() : nullptr; +} +void layer_state_t::updateInputWindowInfo(sp<gui::WindowInfoHandle>&& info) { + what |= eInputInfoChanged; + mNotDefCmpState.windowInfoHandle = std::move(info); +} + +bool layer_state_t::NotDefaultComparableState::operator==( + const NotDefaultComparableState& rhs) const { + return transparentRegion.hasSameRects(rhs.transparentRegion) && + surfaceDamageRegion.hasSameRects(rhs.surfaceDamageRegion) && + isSameWindowHandle(windowInfoHandle, rhs.windowInfoHandle) && + isSameSurfaceControl(relativeLayerSurfaceControl, rhs.relativeLayerSurfaceControl) && + isSameSurfaceControl(parentSurfaceControlForChild, rhs.parentSurfaceControlForChild); +} // ------------------------------- InputWindowCommands ---------------------------------------- @@ -993,13 +1063,13 @@ status_t BufferData::readFromParcel(const Parcel* input) { bool tmpBool = false; SAFE_PARCEL(input->readBool, &tmpBool); if (tmpBool) { - buffer = new GraphicBuffer(); + buffer = sp<GraphicBuffer>::make(); SAFE_PARCEL(input->read, *buffer); } SAFE_PARCEL(input->readBool, &tmpBool); if (tmpBool) { - acquireFence = new Fence(); + acquireFence = sp<Fence>::make(); SAFE_PARCEL(input->read, *acquireFence); } @@ -1026,8 +1096,8 @@ status_t BufferData::readFromParcel(const Parcel* input) { } status_t TrustedPresentationListener::writeToParcel(Parcel* parcel) const { - SAFE_PARCEL(parcel->writeStrongBinder, callbackInterface); - SAFE_PARCEL(parcel->writeInt32, callbackId); + SAFE_PARCEL(parcel->writeStrongBinder, mState.callbackInterface); + SAFE_PARCEL(parcel->writeInt32, mState.callbackId); return NO_ERROR; } @@ -1035,9 +1105,9 @@ status_t TrustedPresentationListener::readFromParcel(const Parcel* parcel) { sp<IBinder> tmpBinder = nullptr; SAFE_PARCEL(parcel->readNullableStrongBinder, &tmpBinder); if (tmpBinder) { - callbackInterface = checked_interface_cast<ITransactionCompletedListener>(tmpBinder); + mState.callbackInterface = checked_interface_cast<ITransactionCompletedListener>(tmpBinder); } - SAFE_PARCEL(parcel->readInt32, &callbackId); + SAFE_PARCEL(parcel->readInt32, &mState.callbackId); return NO_ERROR; } diff --git a/libs/gui/ScreenCaptureResults.cpp b/libs/gui/ScreenCaptureResults.cpp index 2de023e5b2..30b5785b6a 100644 --- a/libs/gui/ScreenCaptureResults.cpp +++ b/libs/gui/ScreenCaptureResults.cpp @@ -18,6 +18,7 @@ #include <private/gui/ParcelUtils.h> #include <ui/FenceResult.h> +#include <ui/GraphicBuffer.h> namespace android::gui { @@ -54,7 +55,7 @@ status_t ScreenCaptureResults::readFromParcel(const android::Parcel* parcel) { bool hasGraphicBuffer; SAFE_PARCEL(parcel->readBool, &hasGraphicBuffer); if (hasGraphicBuffer) { - buffer = new GraphicBuffer(); + buffer = sp<GraphicBuffer>::make(); SAFE_PARCEL(parcel->read, *buffer); } @@ -79,7 +80,7 @@ status_t ScreenCaptureResults::readFromParcel(const android::Parcel* parcel) { bool hasGainmap; SAFE_PARCEL(parcel->readBool, &hasGainmap); if (hasGainmap) { - optionalGainMap = new GraphicBuffer(); + optionalGainMap = sp<GraphicBuffer>::make(); SAFE_PARCEL(parcel->read, *optionalGainMap); } SAFE_PARCEL(parcel->readFloat, &hdrSdrRatio); diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp index 653b91bcf6..848ae7a154 100644 --- a/libs/gui/StreamSplitter.cpp +++ b/libs/gui/StreamSplitter.cpp @@ -47,7 +47,7 @@ status_t StreamSplitter::createSplitter( return BAD_VALUE; } - sp<StreamSplitter> splitter(new StreamSplitter(inputQueue)); + sp<StreamSplitter> splitter = sp<StreamSplitter>::make(inputQueue); status_t status = splitter->mInput->consumerConnect(splitter, false); if (status == NO_ERROR) { splitter->mInput->setConsumerName(String8("StreamSplitter")); @@ -82,7 +82,7 @@ status_t StreamSplitter::addOutput( Mutex::Autolock lock(mMutex); IGraphicBufferProducer::QueueBufferOutput queueBufferOutput; - sp<OutputListener> listener(new OutputListener(this, outputQueue)); + sp<OutputListener> listener = sp<OutputListener>::make(this, outputQueue); IInterface::asBinder(outputQueue)->linkToDeath(listener); status_t status = outputQueue->connect(listener, NATIVE_WINDOW_API_CPU, /* producerControlledByApp */ false, &queueBufferOutput); @@ -140,7 +140,7 @@ void StreamSplitter::onFrameAvailable(const BufferItem& /* item */) { // Initialize our reference count for this buffer mBuffers.add(bufferItem.mGraphicBuffer->getId(), - new BufferTracker(bufferItem.mGraphicBuffer)); + sp<BufferTracker>::make(bufferItem.mGraphicBuffer)); IGraphicBufferProducer::QueueBufferInput queueInput( bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp, diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index ec23365e1f..63dcfbcb9b 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -509,7 +509,7 @@ int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, if (result != OK) { return result; } - sp<Fence> fence(new Fence(fenceFd)); + sp<Fence> fence = sp<Fence>::make(fenceFd); int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED"); if (waitResult != OK) { ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d", @@ -979,7 +979,7 @@ int Surface::cancelBuffer(android_native_buffer_t* buffer, } return OK; } - sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); + sp<Fence> fence(fenceFd >= 0 ? sp<Fence>::make(fenceFd) : Fence::NO_FENCE); mGraphicBufferProducer->cancelBuffer(i, fence); if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) { @@ -1017,7 +1017,7 @@ int Surface::cancelBuffers(const std::vector<BatchBuffer>& buffers) { ALOGE("%s: cannot find slot number for cancelled buffer", __FUNCTION__); badSlotResult = slot; } else { - sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); + sp<Fence> fence(fenceFd >= 0 ? sp<Fence>::make(fenceFd) : Fence::NO_FENCE); cancelBufferInputs[numBuffersCancelled].slot = slot; cancelBufferInputs[numBuffersCancelled++].fence = fence; } @@ -1078,7 +1078,7 @@ void Surface::getQueueBufferInputLocked(android_native_buffer_t* buffer, int fen Rect crop(Rect::EMPTY_RECT); mCrop.intersect(Rect(buffer->width, buffer->height), &crop); - sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); + sp<Fence> fence(fenceFd >= 0 ? sp<Fence>::make(fenceFd) : Fence::NO_FENCE); IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, static_cast<android_dataspace>(mDataSpace), crop, mScalingMode, mTransform ^ mStickyTransform, fence, mStickyTransform, @@ -2092,7 +2092,7 @@ bool Surface::transformToDisplayInverse() const { } int Surface::connect(int api) { - static sp<SurfaceListener> listener = new StubSurfaceListener(); + static sp<SurfaceListener> listener = sp<StubSurfaceListener>::make(); return connect(api, listener); } @@ -2104,7 +2104,7 @@ int Surface::connect(int api, const sp<SurfaceListener>& listener, bool reportBu mReportRemovedBuffers = reportBufferRemoval; if (listener != nullptr) { - mListenerProxy = new ProducerListenerProxy(this, listener); + mListenerProxy = sp<ProducerListenerProxy>::make(this, listener); } int err = diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index cabde22c6d..b0650d56ff 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -19,6 +19,7 @@ #include <semaphore.h> #include <stdint.h> #include <sys/types.h> +#include <algorithm> #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/DisplayState.h> @@ -122,7 +123,7 @@ bool ComposerService::connectLocked() { explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { } }; - mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this)); + mDeathObserver = sp<DeathObserver>::make(*const_cast<ComposerService*>(this)); IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver); return true; } @@ -169,7 +170,7 @@ bool ComposerServiceAIDL::connectLocked() { explicit DeathObserver(ComposerServiceAIDL& mgr) : mComposerService(mgr) {} }; - mDeathObserver = new DeathObserver(*const_cast<ComposerServiceAIDL*>(this)); + mDeathObserver = sp<DeathObserver>::make(*const_cast<ComposerServiceAIDL*>(this)); IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver); return true; } @@ -201,7 +202,7 @@ public: DefaultComposerClient& dc = DefaultComposerClient::getInstance(); Mutex::Autolock _l(dc.mLock); if (dc.mClient == nullptr) { - dc.mClient = new SurfaceComposerClient; + dc.mClient = sp<SurfaceComposerClient>::make(); } return dc.mClient; } @@ -398,7 +399,7 @@ void TransactionCompletedListener::setInstance(const sp<TransactionCompletedList sp<TransactionCompletedListener> TransactionCompletedListener::getInstance() { std::lock_guard<std::mutex> lock(sListenerInstanceMutex); if (sInstance == nullptr) { - sInstance = new TransactionCompletedListener; + sInstance = sp<TransactionCompletedListener>::make(); } return sInstance; } @@ -690,7 +691,7 @@ TransactionCompletedListener::addTrustedPresentationCallback(TrustedPresentation std::scoped_lock<std::mutex> lock(mMutex); mTrustedPresentationCallbacks[id] = std::tuple<TrustedPresentationCallback, void*>(tpc, context); - return new SurfaceComposerClient::PresentationCallbackRAII(this, id); + return sp<SurfaceComposerClient::PresentationCallbackRAII>::make(this, id); } void TransactionCompletedListener::clearTrustedPresentationCallback(int id) { @@ -742,7 +743,7 @@ void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId); */ class BufferCache : public Singleton<BufferCache> { public: - BufferCache() : token(new BBinder()) {} + BufferCache() : token(sp<BBinder>::make()) {} sp<IBinder> getToken() { return IInterface::asBinder(TransactionCompletedListener::getIInstance()); @@ -823,36 +824,25 @@ void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId) { // --------------------------------------------------------------------------- SurfaceComposerClient::Transaction::Transaction() { - mId = generateId(); + mState.mId = generateId(); mTransactionCompletedListener = TransactionCompletedListener::getInstance(); } -SurfaceComposerClient::Transaction::Transaction(const Transaction& other) - : mId(other.mId), - mAnimation(other.mAnimation), - mEarlyWakeupStart(other.mEarlyWakeupStart), - mEarlyWakeupEnd(other.mEarlyWakeupEnd), - mMayContainBuffer(other.mMayContainBuffer), - mDesiredPresentTime(other.mDesiredPresentTime), - mIsAutoTimestamp(other.mIsAutoTimestamp), - mFrameTimelineInfo(other.mFrameTimelineInfo), - mApplyToken(other.mApplyToken) { - mDisplayStates = other.mDisplayStates; - mComposerStates = other.mComposerStates; - mInputWindowCommands = other.mInputWindowCommands; +SurfaceComposerClient::Transaction::Transaction(const Transaction& other) { + mState = other.mState; mListenerCallbacks = other.mListenerCallbacks; mTransactionCompletedListener = TransactionCompletedListener::getInstance(); } void SurfaceComposerClient::Transaction::sanitize(int pid, int uid) { uint32_t permissions = LayerStatePermissions::getTransactionPermissions(pid, uid); - for (auto & [handle, composerState] : mComposerStates) { + for (auto& composerState : mState.mComposerStates) { composerState.state.sanitize(permissions); } - if (!mInputWindowCommands.empty() && + if (!mState.mInputWindowCommands.empty() && (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) { ALOGE("Only privileged callers are allowed to send input commands."); - mInputWindowCommands.clear(); + mState.mInputWindowCommands.clear(); } } @@ -867,33 +857,10 @@ SurfaceComposerClient::Transaction::createFromParcel(const Parcel* parcel) { status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel) { - const uint64_t transactionId = parcel->readUint64(); - const bool animation = parcel->readBool(); - const bool earlyWakeupStart = parcel->readBool(); - const bool earlyWakeupEnd = parcel->readBool(); - const int64_t desiredPresentTime = parcel->readInt64(); - const bool isAutoTimestamp = parcel->readBool(); - const bool logCallPoints = parcel->readBool(); - FrameTimelineInfo frameTimelineInfo; - frameTimelineInfo.readFromParcel(parcel); - - sp<IBinder> applyToken; - parcel->readNullableStrongBinder(&applyToken); - size_t count = static_cast<size_t>(parcel->readUint32()); - if (count > parcel->dataSize()) { - return BAD_VALUE; - } - SortedVector<DisplayState> displayStates; - displayStates.setCapacity(count); - for (size_t i = 0; i < count; i++) { - DisplayState displayState; - if (displayState.read(*parcel) == BAD_VALUE) { - return BAD_VALUE; - } - displayStates.add(displayState); - } + TransactionState tmpState; + SAFE_PARCEL(tmpState.readFromParcel, parcel); - count = static_cast<size_t>(parcel->readUint32()); + size_t count = static_cast<size_t>(parcel->readUint32()); if (count > parcel->dataSize()) { return BAD_VALUE; } @@ -922,62 +889,8 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel } } - count = static_cast<size_t>(parcel->readUint32()); - if (count > parcel->dataSize()) { - return BAD_VALUE; - } - std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> composerStates; - composerStates.reserve(count); - for (size_t i = 0; i < count; i++) { - sp<IBinder> surfaceControlHandle; - SAFE_PARCEL(parcel->readStrongBinder, &surfaceControlHandle); - - ComposerState composerState; - if (composerState.read(*parcel) == BAD_VALUE) { - return BAD_VALUE; - } - composerStates[surfaceControlHandle] = composerState; - } - - InputWindowCommands inputWindowCommands; - inputWindowCommands.read(*parcel); - - count = static_cast<size_t>(parcel->readUint32()); - if (count > parcel->dataSize()) { - return BAD_VALUE; - } - std::vector<client_cache_t> uncacheBuffers(count); - for (size_t i = 0; i < count; i++) { - sp<IBinder> tmpBinder; - SAFE_PARCEL(parcel->readStrongBinder, &tmpBinder); - uncacheBuffers[i].token = tmpBinder; - SAFE_PARCEL(parcel->readUint64, &uncacheBuffers[i].id); - } - - count = static_cast<size_t>(parcel->readUint32()); - if (count > parcel->dataSize()) { - return BAD_VALUE; - } - std::vector<uint64_t> mergedTransactionIds(count); - for (size_t i = 0; i < count; i++) { - SAFE_PARCEL(parcel->readUint64, &mergedTransactionIds[i]); - } - - // Parsing was successful. Update the object. - mId = transactionId; - mAnimation = animation; - mEarlyWakeupStart = earlyWakeupStart; - mEarlyWakeupEnd = earlyWakeupEnd; - mDesiredPresentTime = desiredPresentTime; - mIsAutoTimestamp = isAutoTimestamp; - mFrameTimelineInfo = frameTimelineInfo; - mDisplayStates = displayStates; - mListenerCallbacks = listenerCallbacks; - mComposerStates = composerStates; - mInputWindowCommands = inputWindowCommands; - mApplyToken = applyToken; - mUncacheBuffers = std::move(uncacheBuffers); - mMergedTransactionIds = std::move(mergedTransactionIds); + mState = std::move(tmpState); + mListenerCallbacks = std::move(listenerCallbacks); return NO_ERROR; } @@ -995,19 +908,7 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const const_cast<SurfaceComposerClient::Transaction*>(this)->cacheBuffers(); - parcel->writeUint64(mId); - parcel->writeBool(mAnimation); - parcel->writeBool(mEarlyWakeupStart); - parcel->writeBool(mEarlyWakeupEnd); - parcel->writeInt64(mDesiredPresentTime); - parcel->writeBool(mIsAutoTimestamp); - parcel->writeBool(mLogCallPoints); - mFrameTimelineInfo.writeToParcel(parcel); - parcel->writeStrongBinder(mApplyToken); - parcel->writeUint32(static_cast<uint32_t>(mDisplayStates.size())); - for (auto const& displayState : mDisplayStates) { - displayState.write(*parcel); - } + SAFE_PARCEL(mState.writeToParcel, parcel); parcel->writeUint32(static_cast<uint32_t>(mListenerCallbacks.size())); for (auto const& [listener, callbackInfo] : mListenerCallbacks) { @@ -1022,25 +923,6 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const } } - parcel->writeUint32(static_cast<uint32_t>(mComposerStates.size())); - for (auto const& [handle, composerState] : mComposerStates) { - SAFE_PARCEL(parcel->writeStrongBinder, handle); - composerState.write(*parcel); - } - - mInputWindowCommands.write(*parcel); - - SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mUncacheBuffers.size())); - for (const client_cache_t& uncacheBuffer : mUncacheBuffers) { - SAFE_PARCEL(parcel->writeStrongBinder, uncacheBuffer.token.promote()); - SAFE_PARCEL(parcel->writeUint64, uncacheBuffer.id); - } - - SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mMergedTransactionIds.size())); - for (auto mergedTransactionId : mMergedTransactionIds) { - SAFE_PARCEL(parcel->writeUint64, mergedTransactionId); - } - return NO_ERROR; } @@ -1065,42 +947,8 @@ void SurfaceComposerClient::Transaction::releaseBufferIfOverwriting(const layer_ } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) { - while (mMergedTransactionIds.size() + other.mMergedTransactionIds.size() > - MAX_MERGE_HISTORY_LENGTH - 1 && - mMergedTransactionIds.size() > 0) { - mMergedTransactionIds.pop_back(); - } - if (other.mMergedTransactionIds.size() == MAX_MERGE_HISTORY_LENGTH) { - mMergedTransactionIds.insert(mMergedTransactionIds.begin(), - other.mMergedTransactionIds.begin(), - other.mMergedTransactionIds.end() - 1); - } else if (other.mMergedTransactionIds.size() > 0u) { - mMergedTransactionIds.insert(mMergedTransactionIds.begin(), - other.mMergedTransactionIds.begin(), - other.mMergedTransactionIds.end()); - } - mMergedTransactionIds.insert(mMergedTransactionIds.begin(), other.mId); - - for (auto const& [handle, composerState] : other.mComposerStates) { - if (mComposerStates.count(handle) == 0) { - mComposerStates[handle] = composerState; - } else { - if (composerState.state.what & layer_state_t::eBufferChanged) { - releaseBufferIfOverwriting(mComposerStates[handle].state); - } - mComposerStates[handle].state.merge(composerState.state); - } - } - - for (auto const& state : other.mDisplayStates) { - ssize_t index = mDisplayStates.indexOf(state); - if (index < 0) { - mDisplayStates.add(state); - } else { - mDisplayStates.editItemAt(static_cast<size_t>(index)).merge(state); - } - } - + mState.merge(std::move(other.mState), + std::bind(&Transaction::releaseBufferIfOverwriting, this, std::placeholders::_1)); for (const auto& [listener, callbackInfo] : other.mListenerCallbacks) { auto& [callbackIds, surfaceControls] = callbackInfo; mListenerCallbacks[listener].callbackIds.insert(std::make_move_iterator( @@ -1124,53 +972,21 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr } } - for (const auto& cacheId : other.mUncacheBuffers) { - mUncacheBuffers.push_back(cacheId); - } - - mInputWindowCommands.merge(other.mInputWindowCommands); - - mMayContainBuffer |= other.mMayContainBuffer; - mEarlyWakeupStart = mEarlyWakeupStart || other.mEarlyWakeupStart; - mEarlyWakeupEnd = mEarlyWakeupEnd || other.mEarlyWakeupEnd; - mApplyToken = other.mApplyToken; - - mergeFrameTimelineInfo(mFrameTimelineInfo, other.mFrameTimelineInfo); - - mLogCallPoints |= other.mLogCallPoints; - if (mLogCallPoints) { - ALOG(LOG_DEBUG, LOG_SURFACE_CONTROL_REGISTRY, - "Transaction %" PRIu64 " merged with transaction %" PRIu64, other.getId(), mId); - } - other.clear(); return *this; } void SurfaceComposerClient::Transaction::clear() { - mComposerStates.clear(); - mDisplayStates.clear(); + mState.clear(); mListenerCallbacks.clear(); - mInputWindowCommands.clear(); - mUncacheBuffers.clear(); - mMayContainBuffer = false; - mAnimation = false; - mEarlyWakeupStart = false; - mEarlyWakeupEnd = false; - mDesiredPresentTime = 0; - mIsAutoTimestamp = true; - mFrameTimelineInfo = {}; - mApplyToken = nullptr; - mMergedTransactionIds.clear(); - mLogCallPoints = false; } -uint64_t SurfaceComposerClient::Transaction::getId() { - return mId; +uint64_t SurfaceComposerClient::Transaction::getId() const { + return mState.mId; } std::vector<uint64_t> SurfaceComposerClient::Transaction::getMergedTransactionIds() { - return mMergedTransactionIds; + return mState.mMergedTransactionIds; } void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { @@ -1179,12 +995,13 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { client_cache_t uncacheBuffer; uncacheBuffer.token = BufferCache::getInstance().getToken(); uncacheBuffer.id = cacheId; - Vector<ComposerState> composerStates; - Vector<DisplayState> displayStates; - status_t status = sf->setTransactionState(FrameTimelineInfo{}, composerStates, displayStates, - ISurfaceComposer::eOneWay, - Transaction::getDefaultApplyToken(), {}, systemTime(), - true, {uncacheBuffer}, false, {}, generateId(), {}); + TransactionState state; + state.mId = generateId(); + state.mApplyToken = Transaction::getDefaultApplyToken(); + state.mUncacheBuffers.emplace_back(std::move(uncacheBuffer)); + state.mFlags = ISurfaceComposer::eOneWay; + state.mDesiredPresentTime = systemTime(); + status_t status = sf->setTransactionState(std::move(state)); if (status != NO_ERROR) { ALOGE_AND_TRACE("SurfaceComposerClient::doUncacheBufferTransaction - %s", strerror(-status)); @@ -1192,13 +1009,13 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { } void SurfaceComposerClient::Transaction::cacheBuffers() { - if (!mMayContainBuffer) { + if (!mState.mMayContainBuffer) { return; } size_t count = 0; - for (auto& [handle, cs] : mComposerStates) { - layer_state_t* s = &(mComposerStates[handle].state); + for (auto& cs : mState.mComposerStates) { + layer_state_t* s = &cs.state; if (!(s->what & layer_state_t::eBufferChanged)) { continue; } else if (s->bufferData && @@ -1225,7 +1042,7 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { std::optional<client_cache_t> uncacheBuffer; cacheId = BufferCache::getInstance().cache(s->bufferData->buffer, uncacheBuffer); if (uncacheBuffer) { - mUncacheBuffers.push_back(*uncacheBuffer); + mState.mUncacheBuffers.emplace_back(*uncacheBuffer); } } s->bufferData->flags |= BufferData::BufferDataChange::cachedBufferChanged; @@ -1294,8 +1111,7 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay /*callbackContext=*/nullptr); } - bool hasListenerCallbacks = !mListenerCallbacks.empty(); - std::vector<ListenerCallbacks> listenerCallbacks; + mState.mHasListenerCallbacks = !mListenerCallbacks.empty(); // For every listener with registered callbacks for (const auto& [listener, callbackInfo] : mListenerCallbacks) { auto& [callbackIds, surfaceControls] = callbackInfo; @@ -1304,7 +1120,8 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay } if (surfaceControls.empty()) { - listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds)); + mState.mListenerCallbacks.emplace_back(IInterface::asBinder(listener), + std::move(callbackIds)); } else { // If the listener has any SurfaceControls set on this Transaction update the surface // state @@ -1316,53 +1133,33 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay } std::vector<CallbackId> callbacks(callbackIds.begin(), callbackIds.end()); s->what |= layer_state_t::eHasListenerCallbacksChanged; - s->listeners.emplace_back(IInterface::asBinder(listener), callbacks); + s->listeners.emplace_back(IInterface::asBinder(listener), std::move(callbacks)); } } } cacheBuffers(); - Vector<ComposerState> composerStates; - Vector<DisplayState> displayStates; - uint32_t flags = 0; - - for (auto const& kv : mComposerStates) { - composerStates.add(kv.second); - } - - displayStates = std::move(mDisplayStates); - - if (mAnimation) { - flags |= ISurfaceComposer::eAnimation; - } if (oneWay) { if (synchronous) { ALOGE("Transaction attempted to set synchronous and one way at the same time" " this is an invalid request. Synchronous will win for safety"); } else { - flags |= ISurfaceComposer::eOneWay; + mState.mFlags |= ISurfaceComposer::eOneWay; } } - // If both mEarlyWakeupStart and mEarlyWakeupEnd are set + // If both ISurfaceComposer::eEarlyWakeupStart and ISurfaceComposer::eEarlyWakeupEnd are set // it is equivalent for none - if (mEarlyWakeupStart && !mEarlyWakeupEnd) { - flags |= ISurfaceComposer::eEarlyWakeupStart; - } - if (mEarlyWakeupEnd && !mEarlyWakeupStart) { - flags |= ISurfaceComposer::eEarlyWakeupEnd; + uint32_t wakeupFlags = ISurfaceComposer::eEarlyWakeupStart | ISurfaceComposer::eEarlyWakeupEnd; + if ((mState.mFlags & wakeupFlags) == wakeupFlags) { + mState.mFlags &= ~(wakeupFlags); } - - sp<IBinder> applyToken = mApplyToken ? mApplyToken : getDefaultApplyToken(); + if (!mState.mApplyToken) mState.mApplyToken = getDefaultApplyToken(); sp<ISurfaceComposer> sf(ComposerService::getComposerService()); - status_t binderStatus = - sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, - applyToken, mInputWindowCommands, mDesiredPresentTime, - mIsAutoTimestamp, mUncacheBuffers, hasListenerCallbacks, - listenerCallbacks, mId, mMergedTransactionIds); - mId = generateId(); + status_t binderStatus = sf->setTransactionState(std::move(mState)); + mState.mId = generateId(); // Clear the current states and flags clear(); @@ -1371,15 +1168,15 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay syncCallback->wait(); } - if (mLogCallPoints) { - ALOG(LOG_DEBUG, LOG_SURFACE_CONTROL_REGISTRY, "Transaction %" PRIu64 " applied", mId); + if (mState.mLogCallPoints) { + ALOG(LOG_DEBUG, LOG_SURFACE_CONTROL_REGISTRY, "Transaction %" PRIu64 " applied", getId()); } mStatus = NO_ERROR; return binderStatus; } -sp<IBinder> SurfaceComposerClient::Transaction::sApplyToken = new BBinder(); +sp<IBinder> SurfaceComposerClient::Transaction::sApplyToken = sp<BBinder>::make(); std::mutex SurfaceComposerClient::Transaction::sApplyTokenMutex; @@ -1407,17 +1204,22 @@ status_t SurfaceComposerClient::Transaction::sendSurfaceFlushJankDataTransaction } void SurfaceComposerClient::Transaction::enableDebugLogCallPoints() { - mLogCallPoints = true; + mState.mLogCallPoints = true; } // --------------------------------------------------------------------------- sp<IBinder> SurfaceComposerClient::createVirtualDisplay(const std::string& displayName, - bool isSecure, const std::string& uniqueId, + bool isSecure, bool optimizeForPower, + const std::string& uniqueId, float requestedRefreshRate) { + const gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy = optimizeForPower + ? gui::ISurfaceComposer::OptimizationPolicy::optimizeForPower + : gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance; sp<IBinder> display = nullptr; binder::Status status = ComposerServiceAIDL::getComposerService()->createVirtualDisplay(displayName, isSecure, + optimizationPolicy, uniqueId, requestedRefreshRate, &display); @@ -1437,9 +1239,8 @@ std::vector<PhysicalDisplayId> SurfaceComposerClient::getPhysicalDisplayIds() { ComposerServiceAIDL::getComposerService()->getPhysicalDisplayIds(&displayIds); if (status.isOk()) { physicalDisplayIds.reserve(displayIds.size()); - for (auto item : displayIds) { - auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(item)); - physicalDisplayIds.push_back(*id); + for (auto id : displayIds) { + physicalDisplayIds.push_back(PhysicalDisplayId::fromValue(static_cast<uint64_t>(id))); } } return physicalDisplayIds; @@ -1461,31 +1262,19 @@ std::optional<gui::StalledTransactionInfo> SurfaceComposerClient::getStalledTran } void SurfaceComposerClient::Transaction::setAnimationTransaction() { - mAnimation = true; + mState.mFlags |= ISurfaceComposer::eAnimation; } void SurfaceComposerClient::Transaction::setEarlyWakeupStart() { - mEarlyWakeupStart = true; + mState.mFlags |= ISurfaceComposer::eEarlyWakeupStart; } void SurfaceComposerClient::Transaction::setEarlyWakeupEnd() { - mEarlyWakeupEnd = true; + mState.mFlags |= ISurfaceComposer::eEarlyWakeupEnd; } layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) { - auto handle = sc->getLayerStateHandle(); - - if (mComposerStates.count(handle) == 0) { - // we don't have it, add an initialized layer_state to our list - ComposerState s; - - s.state.surface = handle; - s.state.layerId = sc->getLayerId(); - - mComposerStates[handle] = s; - } - - return &(mComposerStates[handle].state); + return mState.getLayerState(sc); } void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback( @@ -1543,11 +1332,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setRelat mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eRelativeLayerChanged; - s->what &= ~layer_state_t::eLayerChanged; - s->relativeLayerSurfaceControl = relativeTo; - s->z = z; - + s->updateRelativeLayer(relativeTo, z); registerSurfaceControlForCallback(sc); return *this; } @@ -1577,9 +1362,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrans mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eTransparentRegionChanged; - s->transparentRegion = transparentRegion; - + s->updateTransparentRegion(transparentRegion); registerSurfaceControlForCallback(sc); return *this; } @@ -1695,6 +1478,18 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCorne return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setClientDrawnCornerRadius( + const sp<SurfaceControl>& sc, float clientDrawnCornerRadius) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eClientDrawnCornerRadiusChanged; + s->clientDrawnCornerRadius = clientDrawnCornerRadius; + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackgroundBlurRadius( const sp<SurfaceControl>& sc, int backgroundBlurRadius) { layer_state_t* s = getLayerState(sc); @@ -1729,9 +1524,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparent if (SurfaceControl::isSameSurface(sc, newParent)) { return *this; } - s->what |= layer_state_t::eReparent; - s->parentSurfaceControlForChild = newParent ? newParent->getParentingLayer() : nullptr; - + s->updateParentLayer(newParent); registerSurfaceControlForCallback(sc); return *this; } @@ -1857,8 +1650,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe setReleaseBufferCallback(bufferData.get(), callback); } - if (mIsAutoTimestamp) { - mDesiredPresentTime = systemTime(); + if (mState.mIsAutoTimestamp) { + mState.mDesiredPresentTime = systemTime(); } s->what |= layer_state_t::eBufferChanged; s->bufferData = std::move(bufferData); @@ -1876,7 +1669,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe const std::vector<SurfaceControlStats>&) {}, nullptr); - mMayContainBuffer = true; + mState.mMayContainBuffer = true; return *this; } @@ -1961,9 +1754,9 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDesir } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLuts( - const sp<SurfaceControl>& sc, const base::unique_fd& lutFd, - const std::vector<int32_t>& offsets, const std::vector<int32_t>& dimensions, - const std::vector<int32_t>& sizes, const std::vector<int32_t>& samplingKeys) { + const sp<SurfaceControl>& sc, base::unique_fd&& lutFd, const std::vector<int32_t>& offsets, + const std::vector<int32_t>& dimensions, const std::vector<int32_t>& sizes, + const std::vector<int32_t>& samplingKeys) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; @@ -1972,8 +1765,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLuts( s->what |= layer_state_t::eLutsChanged; if (lutFd.ok()) { - s->luts = std::make_shared<gui::DisplayLuts>(base::unique_fd(dup(lutFd.get())), offsets, - dimensions, sizes, samplingKeys); + s->luts = std::make_shared<gui::DisplayLuts>(std::move(lutFd), offsets, dimensions, sizes, + samplingKeys); } else { s->luts = nullptr; } @@ -2017,9 +1810,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSurfa mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eSurfaceDamageRegionChanged; - s->surfaceDamageRegion = surfaceDamageRegion; - + s->updateSurfaceDamageRegion(surfaceDamageRegion); registerSurfaceControlForCallback(sc); return *this; } @@ -2054,8 +1845,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSideb SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDesiredPresentTime( nsecs_t desiredPresentTime) { - mDesiredPresentTime = desiredPresentTime; - mIsAutoTimestamp = false; + mState.mDesiredPresentTime = desiredPresentTime; + mState.mIsAutoTimestamp = false; return *this; } @@ -2138,21 +1929,20 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInput mStatus = BAD_INDEX; return *this; } - s->windowInfoHandle = std::move(info); - s->what |= layer_state_t::eInputInfoChanged; + s->updateInputWindowInfo(std::move(info)); return *this; } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocusedWindow( const FocusRequest& request) { - mInputWindowCommands.focusRequests.push_back(request); + mState.mInputWindowCommands.addFocusRequest(request); return *this; } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::addWindowInfosReportedListener( sp<gui::IWindowInfosReportedListener> windowInfosReportedListener) { - mInputWindowCommands.windowInfosReportedListeners.insert(windowInfosReportedListener); + mState.mInputWindowCommands.addWindowInfosReportedListener(windowInfosReportedListener); return *this; } @@ -2316,7 +2106,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixed SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineInfo( const FrameTimelineInfo& frameTimelineInfo) { - mergeFrameTimelineInfo(mFrameTimelineInfo, frameTimelineInfo); + mState.mergeFrameTimelineInfo(frameTimelineInfo); return *this; } @@ -2355,7 +2145,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrust SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setApplyToken( const sp<IBinder>& applyToken) { - mApplyToken = applyToken; + mState.mApplyToken = applyToken; return *this; } @@ -2372,10 +2162,6 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setStret return *this; } -bool SurfaceComposerClient::flagEdgeExtensionEffectUseShader() { - return com::android::graphics::libgui::flags::edge_extension_shader(); -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setEdgeExtensionEffect( const sp<SurfaceControl>& sc, const gui::EdgeExtensionParameters& effect) { layer_state_t* s = getLayerState(sc); @@ -2487,15 +2273,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setConte // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) { - DisplayState s; - s.token = token; - ssize_t index = mDisplayStates.indexOf(s); - if (index < 0) { - // we don't have it, add an initialized layer_state to our list - s.what = 0; - index = mDisplayStates.add(s); - } - return mDisplayStates.editItemAt(static_cast<size_t>(index)); + return mState.getDisplayState(token); } status_t SurfaceComposerClient::Transaction::setDisplaySurface(const sp<IBinder>& token, @@ -2548,20 +2326,6 @@ void SurfaceComposerClient::Transaction::setDisplaySize(const sp<IBinder>& token s.what |= DisplayState::eDisplaySizeChanged; } -// copied from FrameTimelineInfo::merge() -void SurfaceComposerClient::Transaction::mergeFrameTimelineInfo(FrameTimelineInfo& t, - const FrameTimelineInfo& other) { - // When merging vsync Ids we take the oldest valid one - if (t.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID && - other.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { - if (other.vsyncId > t.vsyncId) { - t = other; - } - } else if (t.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) { - t = other; - } -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrustedPresentationCallback( const sp<SurfaceControl>& sc, TrustedPresentationCallback cb, @@ -2578,8 +2342,9 @@ SurfaceComposerClient::Transaction::setTrustedPresentationCallback( } s->what |= layer_state_t::eTrustedPresentationInfoChanged; s->trustedPresentationThresholds = thresholds; - s->trustedPresentationListener.callbackInterface = TransactionCompletedListener::getIInstance(); - s->trustedPresentationListener.callbackId = sc->getLayerId(); + s->trustedPresentationListener.configure( + {.callbackInterface = TransactionCompletedListener::getIInstance(), + .callbackId = sc->getLayerId()}); return *this; } @@ -2595,8 +2360,7 @@ SurfaceComposerClient::Transaction::clearTrustedPresentationCallback(const sp<Su } s->what |= layer_state_t::eTrustedPresentationInfoChanged; s->trustedPresentationThresholds = TrustedPresentationThresholds(); - s->trustedPresentationListener.callbackInterface = nullptr; - s->trustedPresentationListener.callbackId = -1; + s->trustedPresentationListener.clear(); return *this; } @@ -2689,9 +2453,9 @@ status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32 } ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); if (err == NO_ERROR) { - *outSurface = new SurfaceControl(this, result.handle, result.layerId, - toString(result.layerName), w, h, format, - result.transformHint, flags); + *outSurface = sp<SurfaceControl>::make(this, result.handle, result.layerId, + toString(result.layerName), w, h, format, + result.transformHint, flags); } } return err; @@ -2707,7 +2471,8 @@ sp<SurfaceControl> SurfaceComposerClient::mirrorSurface(SurfaceControl* mirrorFr const binder::Status status = mClient->mirrorSurface(mirrorFromHandle, &result); const status_t err = statusTFromBinderStatus(status); if (err == NO_ERROR) { - return new SurfaceControl(this, result.handle, result.layerId, toString(result.layerName)); + return sp<SurfaceControl>::make(this, result.handle, result.layerId, + toString(result.layerName)); } return nullptr; } @@ -2717,7 +2482,8 @@ sp<SurfaceControl> SurfaceComposerClient::mirrorDisplay(DisplayId displayId) { const binder::Status status = mClient->mirrorDisplay(displayId.value, &result); const status_t err = statusTFromBinderStatus(status); if (err == NO_ERROR) { - return new SurfaceControl(this, result.handle, result.layerId, toString(result.layerName)); + return sp<SurfaceControl>::make(this, result.handle, result.layerId, + toString(result.layerName)); } return nullptr; } @@ -2780,6 +2546,7 @@ status_t SurfaceComposerClient::getStaticDisplayInfo(int64_t displayId, if (status.isOk()) { // convert gui::StaticDisplayInfo to ui::StaticDisplayInfo outInfo->connectionType = static_cast<ui::DisplayConnectionType>(ginfo.connectionType); + outInfo->port = ginfo.port; outInfo->density = ginfo.density; outInfo->secure = ginfo.secure; outInfo->installOrientation = static_cast<ui::Rotation>(ginfo.installOrientation); diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index f126c0be2f..1eb9b87c3c 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -141,7 +141,8 @@ sp<Surface> SurfaceControl::generateSurfaceLocked() ISurfaceComposerClient::eOpaque); mBbqChild = mClient->createSurface(String8::format("[BBQ] %s", mName.c_str()), 0, 0, mFormat, flags, mHandle, {}, &ignore); - mBbq = sp<BLASTBufferQueue>::make("[BBQ]" + mName, mBbqChild, mWidth, mHeight, mFormat); + mBbq = sp<BLASTBufferQueue>::make("[BBQ] " + mName, /* updateDestinationFrame */ true); + mBbq->update(mBbqChild, mWidth, mHeight, mFormat); // This surface is always consumed by SurfaceFlinger, so the // producerControlledByApp value doesn't matter; using false. @@ -268,10 +269,11 @@ status_t SurfaceControl::readFromParcel(const Parcel& parcel, SAFE_PARCEL(parcel.readUint32, &format); // We aren't the original owner of the surface. - *outSurfaceControl = new SurfaceControl(new SurfaceComposerClient( - interface_cast<ISurfaceComposerClient>(client)), - handle.get(), layerId, layerName, width, height, format, - transformHint); + *outSurfaceControl = + sp<SurfaceControl>::make(sp<SurfaceComposerClient>::make( + interface_cast<ISurfaceComposerClient>(client)), + handle, layerId, layerName, width, height, format, + transformHint); return NO_ERROR; } diff --git a/libs/gui/TEST_MAPPING b/libs/gui/TEST_MAPPING index a590c86ceb..14d6df62cb 100644 --- a/libs/gui/TEST_MAPPING +++ b/libs/gui/TEST_MAPPING @@ -60,5 +60,34 @@ } ] } + ], + "postsubmit": [ + { + "name": "libgui_test", + "keywords": [ "primary-device" ], + "options": [ + // TODO(b/397776630): Failing on real devices. + { + "exclude-filter": "InputSurfacesTest#input_respects_scaled_touchable_region_overflow" + }, + // TODO(b/233363648): Failing on real devices. + { + "exclude-filter": "SurfaceTextureGLTest#TexturingFromCpuFilledYV12BufferNpot" + }, + { + "exclude-filter": "SurfaceTextureGLTest#TexturingFromCpuFilledYV12BufferPow2" + }, + { + "exclude-filter": "SurfaceTextureGLTest#TexturingFromCpuFilledYV12BufferWithCrop" + }, + // TODO(b/233363648): Flaky on real devices. + { + "exclude-filter": "SurfaceTextureGLToGLTest#EglMakeCurrentBeforeConsumerDeathUnrefsBuffers" + }, + { + "exclude-filter": "SurfaceTextureGLToGLTest#EglMakeCurrentAfterConsumerDeathUnrefsBuffers" + } + ] + } ] } diff --git a/libs/gui/TransactionState.cpp b/libs/gui/TransactionState.cpp new file mode 100644 index 0000000000..9e09bc2644 --- /dev/null +++ b/libs/gui/TransactionState.cpp @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "TransactionState" +#include <gui/LayerState.h> +#include <gui/SurfaceComposerClient.h> +#include <gui/TransactionState.h> +#include <private/gui/ParcelUtils.h> +#include <algorithm> + +namespace android { + +status_t TransactionState::writeToParcel(Parcel* parcel) const { + SAFE_PARCEL(parcel->writeUint64, mId); + SAFE_PARCEL(parcel->writeUint32, mFlags); + SAFE_PARCEL(parcel->writeInt64, mDesiredPresentTime); + SAFE_PARCEL(parcel->writeBool, mIsAutoTimestamp); + SAFE_PARCEL(parcel->writeParcelable, mFrameTimelineInfo); + SAFE_PARCEL(parcel->writeStrongBinder, mApplyToken); + SAFE_PARCEL(parcel->writeBool, mMayContainBuffer); + SAFE_PARCEL(parcel->writeBool, mLogCallPoints); + + SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mDisplayStates.size())); + for (auto const& displayState : mDisplayStates) { + displayState.write(*parcel); + } + SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mComposerStates.size())); + for (auto const& composerState : mComposerStates) { + composerState.write(*parcel); + } + + mInputWindowCommands.write(*parcel); + SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mUncacheBuffers.size())); + for (const client_cache_t& uncacheBuffer : mUncacheBuffers) { + SAFE_PARCEL(parcel->writeStrongBinder, uncacheBuffer.token.promote()); + SAFE_PARCEL(parcel->writeUint64, uncacheBuffer.id); + } + + SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mMergedTransactionIds.size())); + for (auto mergedTransactionId : mMergedTransactionIds) { + SAFE_PARCEL(parcel->writeUint64, mergedTransactionId); + } + + SAFE_PARCEL(parcel->writeBool, mHasListenerCallbacks); + SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mListenerCallbacks.size())); + for (const auto& [listener, callbackIds] : mListenerCallbacks) { + SAFE_PARCEL(parcel->writeStrongBinder, listener); + SAFE_PARCEL(parcel->writeParcelableVector, callbackIds); + } + + return NO_ERROR; +} + +status_t TransactionState::readFromParcel(const Parcel* parcel) { + SAFE_PARCEL(parcel->readUint64, &mId); + SAFE_PARCEL(parcel->readUint32, &mFlags); + SAFE_PARCEL(parcel->readInt64, &mDesiredPresentTime); + SAFE_PARCEL(parcel->readBool, &mIsAutoTimestamp); + SAFE_PARCEL(parcel->readParcelable, &mFrameTimelineInfo); + SAFE_PARCEL(parcel->readNullableStrongBinder, &mApplyToken); + SAFE_PARCEL(parcel->readBool, &mMayContainBuffer); + SAFE_PARCEL(parcel->readBool, &mLogCallPoints); + + uint32_t count; + SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize()) + mDisplayStates.clear(); + mDisplayStates.reserve(count); + for (size_t i = 0; i < count; i++) { + DisplayState displayState; + if (displayState.read(*parcel) == BAD_VALUE) { + return BAD_VALUE; + } + mDisplayStates.emplace_back(std::move(displayState)); + } + + SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize()) + mComposerStates.clear(); + mComposerStates.reserve(count); + for (size_t i = 0; i < count; i++) { + ComposerState composerState; + if (composerState.read(*parcel) == BAD_VALUE) { + return BAD_VALUE; + } + mComposerStates.emplace_back(std::move(composerState)); + } + + if (status_t status = mInputWindowCommands.read(*parcel) != NO_ERROR) { + return status; + } + + SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize()) + mUncacheBuffers.clear(); + mUncacheBuffers.reserve(count); + for (size_t i = 0; i < count; i++) { + client_cache_t client_cache; + sp<IBinder> tmpBinder; + SAFE_PARCEL(parcel->readStrongBinder, &tmpBinder); + client_cache.token = tmpBinder; + SAFE_PARCEL(parcel->readUint64, &client_cache.id); + mUncacheBuffers.emplace_back(std::move(client_cache)); + } + + SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize()) + mMergedTransactionIds.clear(); + mMergedTransactionIds.resize(count); + for (size_t i = 0; i < count; i++) { + SAFE_PARCEL(parcel->readUint64, &mMergedTransactionIds[i]); + } + + SAFE_PARCEL(parcel->readBool, &mHasListenerCallbacks); + SAFE_PARCEL_READ_SIZE(parcel->readUint32, &count, parcel->dataSize()); + mListenerCallbacks.clear(); + mListenerCallbacks.reserve(count); + for (uint32_t i = 0; i < count; i++) { + sp<IBinder> tmpBinder; + SAFE_PARCEL(parcel->readStrongBinder, &tmpBinder); + std::vector<CallbackId> callbackIds; + SAFE_PARCEL(parcel->readParcelableVector, &callbackIds); + mListenerCallbacks.emplace_back(tmpBinder, callbackIds); + } + + return NO_ERROR; +} + +void TransactionState::merge(TransactionState&& other, + const std::function<void(layer_state_t&)>& onBufferOverwrite) { + while (mMergedTransactionIds.size() + other.mMergedTransactionIds.size() > + MAX_MERGE_HISTORY_LENGTH - 1 && + mMergedTransactionIds.size() > 0) { + mMergedTransactionIds.pop_back(); + } + if (other.mMergedTransactionIds.size() == MAX_MERGE_HISTORY_LENGTH) { + mMergedTransactionIds.insert(mMergedTransactionIds.begin(), + other.mMergedTransactionIds.begin(), + other.mMergedTransactionIds.end() - 1); + } else if (other.mMergedTransactionIds.size() > 0u) { + mMergedTransactionIds.insert(mMergedTransactionIds.begin(), + other.mMergedTransactionIds.begin(), + other.mMergedTransactionIds.end()); + } + mMergedTransactionIds.insert(mMergedTransactionIds.begin(), other.mId); + + for (auto const& otherState : other.mComposerStates) { + if (auto it = std::find_if(mComposerStates.begin(), mComposerStates.end(), + [&otherState](const auto& composerState) { + return composerState.state.surface == + otherState.state.surface; + }); + it != mComposerStates.end()) { + if (otherState.state.what & layer_state_t::eBufferChanged) { + onBufferOverwrite(it->state); + } + it->state.merge(otherState.state); + } else { + mComposerStates.push_back(otherState); + } + } + + for (auto const& state : other.mDisplayStates) { + if (auto it = std::find_if(mDisplayStates.begin(), mDisplayStates.end(), + [&state](const auto& displayState) { + return displayState.token == state.token; + }); + it != mDisplayStates.end()) { + it->merge(state); + } else { + mDisplayStates.push_back(state); + } + } + + for (const auto& cacheId : other.mUncacheBuffers) { + mUncacheBuffers.push_back(cacheId); + } + + mInputWindowCommands.merge(other.mInputWindowCommands); + // TODO(b/385156191) Consider merging desired present time. + mFlags |= other.mFlags; + mMayContainBuffer |= other.mMayContainBuffer; + mLogCallPoints |= other.mLogCallPoints; + + // mApplyToken is explicitly not merged. Token should be set before applying the transactions to + // make synchronization decisions a bit simpler. + mergeFrameTimelineInfo(other.mFrameTimelineInfo); + other.clear(); +} + +// copied from FrameTimelineInfo::merge() +void TransactionState::mergeFrameTimelineInfo(const FrameTimelineInfo& other) { + // When merging vsync Ids we take the oldest valid one + if (mFrameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID && + other.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { + if (other.vsyncId > mFrameTimelineInfo.vsyncId) { + mFrameTimelineInfo = other; + } + } else if (mFrameTimelineInfo.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) { + mFrameTimelineInfo = other; + } +} + +void TransactionState::clear() { + mComposerStates.clear(); + mDisplayStates.clear(); + mListenerCallbacks.clear(); + mHasListenerCallbacks = false; + mInputWindowCommands.clear(); + mUncacheBuffers.clear(); + mDesiredPresentTime = 0; + mIsAutoTimestamp = true; + mApplyToken = nullptr; + mFrameTimelineInfo = {}; + mMergedTransactionIds.clear(); + mFlags = 0; + mMayContainBuffer = false; + mLogCallPoints = false; +} + +layer_state_t* TransactionState::getLayerState(const sp<SurfaceControl>& sc) { + auto handle = sc->getLayerStateHandle(); + if (auto it = std::find_if(mComposerStates.begin(), mComposerStates.end(), + [&handle](const auto& composerState) { + return composerState.state.surface == handle; + }); + it != mComposerStates.end()) { + return &it->state; + } + + // we don't have it, add an initialized layer_state to our list + ComposerState s; + s.state.surface = handle; + s.state.layerId = sc->getLayerId(); + mComposerStates.push_back(s); + + return &mComposerStates.back().state; +} + +DisplayState& TransactionState::getDisplayState(const sp<IBinder>& token) { + if (auto it = std::find_if(mDisplayStates.begin(), mDisplayStates.end(), + [token](const auto& display) { return display.token == token; }); + it != mDisplayStates.end()) { + return *it; + } + + // If display state doesn't exist, add a new one. + DisplayState s; + s.token = token; + mDisplayStates.push_back(s); + return mDisplayStates.back(); +} + +}; // namespace android diff --git a/libs/gui/WindowInfo.cpp b/libs/gui/WindowInfo.cpp index 82d2554340..3fb66d1f33 100644 --- a/libs/gui/WindowInfo.cpp +++ b/libs/gui/WindowInfo.cpp @@ -59,6 +59,32 @@ std::ostream& operator<<(std::ostream& out, const Region& region) { return out; } +status_t writeTransform(android::Parcel* parcel, const ui::Transform& transform) { + return parcel->writeFloat(transform.dsdx()) ?: + parcel->writeFloat(transform.dtdx()) ?: + parcel->writeFloat(transform.tx()) ?: + parcel->writeFloat(transform.dtdy()) ?: + parcel->writeFloat(transform.dsdy()) ?: + parcel->writeFloat(transform.ty()); +} + +status_t readTransform(const android::Parcel* parcel, ui::Transform& transform) { + float dsdx, dtdx, tx, dtdy, dsdy, ty; + + const status_t status = parcel->readFloat(&dsdx) ?: + parcel->readFloat(&dtdx) ?: + parcel->readFloat(&tx) ?: + parcel->readFloat(&dtdy) ?: + parcel->readFloat(&dsdy) ?: + parcel->readFloat(&ty); + if (status != OK) { + return status; + } + + transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1}); + return OK; +} + } // namespace void WindowInfo::setInputConfig(ftl::Flags<InputConfig> config, bool value) { @@ -73,10 +99,6 @@ void WindowInfo::addTouchableRegion(const Rect& region) { touchableRegion.orSelf(region); } -bool WindowInfo::supportsSplitTouch() const { - return !inputConfig.test(InputConfig::PREVENT_SPLITTING); -} - bool WindowInfo::isSpy() const { return inputConfig.test(InputConfig::SPY); } @@ -135,12 +157,7 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const { parcel->writeInt32(surfaceInset) ?: parcel->writeFloat(globalScaleFactor) ?: parcel->writeFloat(alpha) ?: - parcel->writeFloat(transform.dsdx()) ?: - parcel->writeFloat(transform.dtdx()) ?: - parcel->writeFloat(transform.tx()) ?: - parcel->writeFloat(transform.dtdy()) ?: - parcel->writeFloat(transform.dsdy()) ?: - parcel->writeFloat(transform.ty()) ?: + writeTransform(parcel, transform) ?: parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?: parcel->writeInt32(ownerPid.val()) ?: parcel->writeInt32(ownerUid.val()) ?: @@ -153,8 +170,12 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const { parcel->writeStrongBinder(touchableRegionCropHandle.promote()) ?: parcel->writeStrongBinder(windowToken) ?: parcel->writeStrongBinder(focusTransferTarget) ?: - parcel->writeBool(canOccludePresentation); + parcel->writeBool(canOccludePresentation) ?: + parcel->writeBool(cloneLayerStackTransform.has_value()); // clang-format on + if (cloneLayerStackTransform) { + status = status ?: writeTransform(parcel, *cloneLayerStackTransform); + } return status; } @@ -174,10 +195,10 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) { return status; } - float dsdx, dtdx, tx, dtdy, dsdy, ty; int32_t lpFlags, lpType, touchOcclusionModeInt, inputConfigInt, ownerPidInt, ownerUidInt, displayIdInt; sp<IBinder> touchableRegionCropHandleSp; + bool hasCloneLayerStackTransform = false; // clang-format off status = parcel->readInt32(&lpFlags) ?: @@ -188,12 +209,7 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) { parcel->readInt32(&surfaceInset) ?: parcel->readFloat(&globalScaleFactor) ?: parcel->readFloat(&alpha) ?: - parcel->readFloat(&dsdx) ?: - parcel->readFloat(&dtdx) ?: - parcel->readFloat(&tx) ?: - parcel->readFloat(&dtdy) ?: - parcel->readFloat(&dsdy) ?: - parcel->readFloat(&ty) ?: + readTransform(parcel, /*byRef*/ transform) ?: parcel->readInt32(&touchOcclusionModeInt) ?: parcel->readInt32(&ownerPidInt) ?: parcel->readInt32(&ownerUidInt) ?: @@ -206,8 +222,8 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) { parcel->readNullableStrongBinder(&touchableRegionCropHandleSp) ?: parcel->readNullableStrongBinder(&windowToken) ?: parcel->readNullableStrongBinder(&focusTransferTarget) ?: - parcel->readBool(&canOccludePresentation); - + parcel->readBool(&canOccludePresentation)?: + parcel->readBool(&hasCloneLayerStackTransform); // clang-format on if (status != OK) { @@ -216,7 +232,6 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) { layoutParamsFlags = ftl::Flags<Flag>(lpFlags); layoutParamsType = static_cast<Type>(lpType); - transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1}); touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt); inputConfig = ftl::Flags<InputConfig>(inputConfigInt); ownerPid = Pid{ownerPidInt}; @@ -224,6 +239,15 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) { touchableRegionCropHandle = touchableRegionCropHandleSp; displayId = ui::LogicalDisplayId{displayIdInt}; + cloneLayerStackTransform = + hasCloneLayerStackTransform ? std::make_optional<ui::Transform>() : std::nullopt; + if (cloneLayerStackTransform) { + status = readTransform(parcel, /*byRef*/ *cloneLayerStackTransform); + if (status != OK) { + return status; + } + } + return OK; } diff --git a/libs/gui/WindowInfosListenerReporter.cpp b/libs/gui/WindowInfosListenerReporter.cpp index 91c9a85149..d633f9f15e 100644 --- a/libs/gui/WindowInfosListenerReporter.cpp +++ b/libs/gui/WindowInfosListenerReporter.cpp @@ -15,6 +15,7 @@ */ #include <android/gui/ISurfaceComposer.h> +#include <android/gui/IWindowInfosListener.h> #include <gui/AidlUtil.h> #include <gui/WindowInfosListenerReporter.h> #include "gui/WindowInfosUpdate.h" @@ -27,7 +28,7 @@ using gui::WindowInfosListener; using gui::aidl_utils::statusTFromBinderStatus; sp<WindowInfosListenerReporter> WindowInfosListenerReporter::getInstance() { - static sp<WindowInfosListenerReporter> sInstance = new WindowInfosListenerReporter; + static sp<WindowInfosListenerReporter> sInstance = sp<WindowInfosListenerReporter>::make(); return sInstance; } @@ -116,7 +117,8 @@ void WindowInfosListenerReporter::reconnect(const sp<gui::ISurfaceComposer>& com std::scoped_lock lock(mListenersMutex); if (!mWindowInfosListeners.empty()) { gui::WindowInfosListenerInfo listenerInfo; - composerService->addWindowInfosListener(this, &listenerInfo); + composerService->addWindowInfosListener(sp<gui::IWindowInfosListener>::fromExisting(this), + &listenerInfo); mWindowInfosPublisher = std::move(listenerInfo.windowInfosPublisher); mListenerId = listenerInfo.listenerId; } diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index da47ee27ba..9b2f089665 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -67,6 +67,11 @@ interface ISurfaceComposer { frameRateOverride = 1 << 1, } + enum OptimizationPolicy { + optimizeForPower = 0, + optimizeForPerformance = 1, + } + /** * Signal that we're done booting. * Requires ACCESS_SURFACE_FLINGER permission @@ -97,6 +102,10 @@ interface ISurfaceComposer { * The name of the virtual display. * isSecure * Whether this virtual display is secure. + * optimizationPolicy + * Whether to optimize for power or performance. Displays that are optimizing for power may + * be dependent on a different display that optimizes for performance when they are on, + * which will guarantee performance for all of the other displays. * uniqueId * The unique ID for the display. * requestedRefreshRate @@ -108,7 +117,7 @@ interface ISurfaceComposer { * requires ACCESS_SURFACE_FLINGER permission. */ @nullable IBinder createVirtualDisplay(@utf8InCpp String displayName, boolean isSecure, - @utf8InCpp String uniqueId, float requestedRefreshRate); + OptimizationPolicy optimizationPolicy, @utf8InCpp String uniqueId, float requestedRefreshRate); /** * Destroy a virtual display. diff --git a/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl b/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl index 0ccda56ef5..7ff332c29e 100644 --- a/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl +++ b/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl @@ -23,6 +23,7 @@ import android.gui.Rotation; /** @hide */ parcelable StaticDisplayInfo { DisplayConnectionType connectionType = DisplayConnectionType.Internal; + int port = -1; float density; boolean secure; @nullable DeviceProductInfo deviceProductInfo; diff --git a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp index fd8ffe1f01..b1a23b309e 100644 --- a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp +++ b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp @@ -971,7 +971,7 @@ inline HGraphicBufferProducer::DisconnectMode toHDisconnectMode( // H2BGraphicBufferProducer status_t H2BGraphicBufferProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { - *buf = new GraphicBuffer(); + *buf = sp<GraphicBuffer>::make(); status_t fnStatus; status_t transStatus = toStatusT(mBase->requestBuffer( static_cast<int32_t>(slot), @@ -999,7 +999,7 @@ status_t H2BGraphicBufferProducer::dequeueBuffer(int* slot, sp<Fence>* fence, ui uint32_t h, ::android::PixelFormat format, uint64_t usage, uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps) { - *fence = new Fence(); + *fence = sp<Fence>::make(); status_t fnStatus; status_t transStatus = toStatusT(mBase->dequeueBuffer( w, h, static_cast<PixelFormat>(format), uint32_t(usage), @@ -1035,8 +1035,8 @@ status_t H2BGraphicBufferProducer::detachBuffer(int slot) { status_t H2BGraphicBufferProducer::detachNextBuffer( sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) { - *outBuffer = new GraphicBuffer(); - *outFence = new Fence(); + *outBuffer = sp<GraphicBuffer>::make(); + *outFence = sp<Fence>::make(); status_t fnStatus; status_t transStatus = toStatusT(mBase->detachNextBuffer( [&fnStatus, outBuffer, outFence] ( @@ -1127,8 +1127,8 @@ int H2BGraphicBufferProducer::query(int what, int* value) { status_t H2BGraphicBufferProducer::connect( const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput* output) { - sp<HProducerListener> tListener = listener == nullptr ? - nullptr : new B2HProducerListener(listener); + sp<HProducerListener> tListener = + listener == nullptr ? nullptr : sp<B2HProducerListener>::make(listener); status_t fnStatus; status_t transStatus = toStatusT(mBase->connect( tListener, static_cast<int32_t>(api), producerControlledByApp, @@ -1205,13 +1205,13 @@ status_t H2BGraphicBufferProducer::getLastQueuedBuffer( hidl_handle const& fence, hidl_array<float, 16> const& transformMatrix) { fnStatus = toStatusT(status); - *outBuffer = new GraphicBuffer(); + *outBuffer = sp<GraphicBuffer>::make(); if (!convertTo(outBuffer->get(), buffer)) { ALOGE("H2BGraphicBufferProducer::getLastQueuedBuffer - " "Invalid output buffer"); fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus; } - *outFence = new Fence(); + *outFence = sp<Fence>::make(); if (!convertTo(outFence->get(), fence)) { ALOGE("H2BGraphicBufferProducer::getLastQueuedBuffer - " "Invalid output fence"); diff --git a/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp index c76d771262..4384bd5faa 100644 --- a/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp +++ b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp @@ -272,7 +272,7 @@ Return<void> B2HGraphicBufferProducer::connect( HConnectionType hConnectionType, bool producerControlledByApp, connect_cb _hidl_cb) { - sp<BProducerListener> bListener = new H2BProducerListener(hListener); + sp<BProducerListener> bListener = sp<H2BProducerListener>::make(hListener); int bConnectionType{}; if (!bListener || !h2b(hConnectionType, &bConnectionType)) { _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{}); diff --git a/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp index ae00a2642e..7121bb7aef 100644 --- a/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp +++ b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp @@ -325,7 +325,7 @@ status_t H2BGraphicBufferProducer::connect( } sp<HProducerListener> hListener = nullptr; if (listener && listener->needsReleaseNotify()) { - hListener = new B2HProducerListener(listener); + hListener = sp<B2HProducerListener>::make(listener); if (!hListener) { LOG(ERROR) << "connect: failed to wrap listener."; return UNKNOWN_ERROR; diff --git a/libs/gui/bufferqueue/2.0/types.cpp b/libs/gui/bufferqueue/2.0/types.cpp index cbd6cad847..c245766b42 100644 --- a/libs/gui/bufferqueue/2.0/types.cpp +++ b/libs/gui/bufferqueue/2.0/types.cpp @@ -147,13 +147,13 @@ bool b2h(sp<BFence> const& from, HFenceWrapper* to) { bool h2b(native_handle_t const* from, sp<BFence>* to) { if (!from || from->numFds == 0) { - *to = new ::android::Fence(); + *to = sp<::android::Fence>::make(); return true; } if (from->numFds != 1 || from->numInts != 0) { return false; } - *to = new BFence(dup(from->data[0])); + *to = sp<BFence>::make(dup(from->data[0])); return true; } diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index 1bc1dd0685..db1b9fb8eb 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -20,6 +20,7 @@ #include <optional> #include <queue> +#include <ftl/small_map.h> #include <gui/BufferItem.h> #include <gui/BufferItemConsumer.h> #include <gui/IGraphicBufferConsumer.h> @@ -36,26 +37,15 @@ namespace android { +// Sizes determined empirically to avoid allocations during common activity. +constexpr size_t kSubmittedBuffersMapSizeHint = 8; +constexpr size_t kDequeueTimestampsMapSizeHint = 32; + class BLASTBufferQueue; class BufferItemConsumer; class BLASTBufferItemConsumer : public BufferItemConsumer { public: -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) - BLASTBufferItemConsumer(const sp<IGraphicBufferProducer>& producer, - const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage, - int bufferCount, bool controlledByApp, wp<BLASTBufferQueue> bbq) - : BufferItemConsumer(producer, consumer, consumerUsage, bufferCount, controlledByApp), -#else - BLASTBufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage, - int bufferCount, bool controlledByApp, wp<BLASTBufferQueue> bbq) - : BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp), -#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) - mBLASTBufferQueue(std::move(bbq)), - mCurrentlyConnected(false), - mPreviouslyConnected(false) { - } - void onDisconnect() override EXCLUDES(mMutex); void addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta* outDelta) override EXCLUDES(mMutex); @@ -76,6 +66,23 @@ protected: #endif private: +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) + BLASTBufferItemConsumer(const sp<IGraphicBufferProducer>& producer, + const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage, + int bufferCount, bool controlledByApp, wp<BLASTBufferQueue> bbq) + : BufferItemConsumer(producer, consumer, consumerUsage, bufferCount, controlledByApp), +#else + BLASTBufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage, + int bufferCount, bool controlledByApp, wp<BLASTBufferQueue> bbq) + : BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp), +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) + mBLASTBufferQueue(std::move(bbq)), + mCurrentlyConnected(false), + mPreviouslyConnected(false) { + } + + friend class sp<BLASTBufferItemConsumer>; + const wp<BLASTBufferQueue> mBLASTBufferQueue; uint64_t mCurrentFrameNumber GUARDED_BY(mMutex) = 0; @@ -89,10 +96,6 @@ private: class BLASTBufferQueue : public ConsumerBase::FrameAvailableListener { public: - BLASTBufferQueue(const std::string& name, bool updateDestinationFrame = true); - BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width, - int height, int32_t format); - sp<IGraphicBufferProducer> getIGraphicBufferProducer() const { return mProducer; } @@ -145,9 +148,9 @@ public: void setTransactionHangCallback(std::function<void(const std::string&)> callback); void setApplyToken(sp<IBinder>); - void setWaitForBufferReleaseCallback(std::function<void()> callback) + void setWaitForBufferReleaseCallback(std::function<void(const nsecs_t)> callback) EXCLUDES(mWaitForBufferReleaseMutex); - std::function<void()> getWaitForBufferReleaseCallback() const + std::function<void(const nsecs_t)> getWaitForBufferReleaseCallback() const EXCLUDES(mWaitForBufferReleaseMutex); virtual ~BLASTBufferQueue(); @@ -155,8 +158,13 @@ public: void onFirstRef() override; private: + // Not public to ensure construction via sp<>::make(). + BLASTBufferQueue(const std::string& name, bool updateDestinationFrame = true); + + friend class sp<BLASTBufferQueue>; friend class BLASTBufferQueueHelper; friend class BBQBufferQueueProducer; + friend class TestBLASTBufferQueue; #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) friend class BBQBufferQueueCore; #endif @@ -208,7 +216,7 @@ private: // Keep a reference to the submitted buffers so we can release when surfaceflinger drops the // buffer or the buffer has been presented and a new buffer is ready to be presented. - std::unordered_map<ReleaseCallbackId, BufferItem, ReleaseBufferCallbackIdHash> mSubmitted + ftl::SmallMap<ReleaseCallbackId, BufferItem, kSubmittedBuffersMapSizeHint> mSubmitted GUARDED_BY(mMutex); // Keep a queue of the released buffers instead of immediately releasing @@ -293,8 +301,8 @@ private: std::mutex mTimestampMutex; // Tracks buffer dequeue times by the client. This info is sent to SurfaceFlinger which uses // it for debugging purposes. - std::unordered_map<uint64_t /* bufferId */, nsecs_t> mDequeueTimestamps - GUARDED_BY(mTimestampMutex); + ftl::SmallMap<uint64_t /* bufferId */, nsecs_t, kDequeueTimestampsMapSizeHint> + mDequeueTimestamps GUARDED_BY(mTimestampMutex); // Keep track of SurfaceControls that have submitted a transaction and BBQ is waiting on a // callback for them. @@ -331,7 +339,8 @@ private: std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex); - std::function<void()> mWaitForBufferReleaseCallback GUARDED_BY(mWaitForBufferReleaseMutex); + std::function<void(const nsecs_t)> mWaitForBufferReleaseCallback + GUARDED_BY(mWaitForBufferReleaseMutex); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) // BufferReleaseChannel is used to communicate buffer releases from SurfaceFlinger to the // client. diff --git a/libs/gui/include/gui/BufferItemConsumer.h b/libs/gui/include/gui/BufferItemConsumer.h index 6810edaf7c..fc31f4636c 100644 --- a/libs/gui/include/gui/BufferItemConsumer.h +++ b/libs/gui/include/gui/BufferItemConsumer.h @@ -47,6 +47,16 @@ class BufferItemConsumer: public ConsumerBase enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT }; enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE }; + static std::tuple<sp<BufferItemConsumer>, sp<Surface>> create( + uint64_t consumerUsage, int bufferCount = DEFAULT_MAX_BUFFERS, + bool controlledByApp = false, bool isConsumerSurfaceFlinger = false); + + static sp<BufferItemConsumer> create(const sp<IGraphicBufferConsumer>& consumer, + uint64_t consumerUsage, + int bufferCount = DEFAULT_MAX_BUFFERS, + bool controlledByApp = false) + __attribute((deprecated("Prefer ctors that create their own surface and consumer."))); + // Create a new buffer item consumer. The consumerUsage parameter determines // the consumer usage flags passed to the graphics allocator. The // bufferCount parameter specifies how many buffers can be locked for user @@ -86,6 +96,14 @@ class BufferItemConsumer: public ConsumerBase status_t acquireBuffer(BufferItem* item, nsecs_t presentWhen, bool waitForFence = true); + // Transfer ownership of a buffer to the BufferQueue. On NO_ERROR, the buffer + // is considered as if it were acquired. Buffer must not be null. + // + // Returns + // - BAD_VALUE if buffer is null + // - INVALID_OPERATION if too many buffers have already been acquired + status_t attachBuffer(const sp<GraphicBuffer>& buffer); + // Returns an acquired buffer to the queue, allowing it to be reused. Since // only a fixed number of buffers may be acquired at a time, old buffers // must be released by calling releaseBuffer to ensure new buffers can be @@ -95,10 +113,8 @@ class BufferItemConsumer: public ConsumerBase status_t releaseBuffer(const BufferItem &item, const sp<Fence>& releaseFence = Fence::NO_FENCE); -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) status_t releaseBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& releaseFence = Fence::NO_FENCE); -#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) protected: #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h index f1c75d3a45..7b97e13649 100644 --- a/libs/gui/include/gui/BufferQueue.h +++ b/libs/gui/include/gui/BufferQueue.h @@ -57,7 +57,7 @@ public: // reference in the BufferQueue class is because we're planning to expose the // consumer side of a BufferQueue as a binder interface, which doesn't support // weak references. - class ProxyConsumerListener : public BnConsumerListener { + class ProxyConsumerListener : public IConsumerListener { public: explicit ProxyConsumerListener(const wp<ConsumerListener>& consumerListener); ~ProxyConsumerListener() override; diff --git a/libs/gui/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h index e00c44eb70..ba6a6a73f4 100644 --- a/libs/gui/include/gui/BufferQueueConsumer.h +++ b/libs/gui/include/gui/BufferQueueConsumer.h @@ -28,8 +28,7 @@ namespace android { class BufferQueueCore; -class BufferQueueConsumer : public BnGraphicBufferConsumer { - +class BufferQueueConsumer : public IGraphicBufferConsumer { public: explicit BufferQueueConsumer(const sp<BufferQueueCore>& core); ~BufferQueueConsumer() override; @@ -65,13 +64,14 @@ public: // any references to the just-released buffer that it might have, as if it // had received a onBuffersReleased() call with a mask set for the released // buffer. - // - // Note that the dependencies on EGL will be removed once we switch to using - // the Android HW Sync HAL. +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + virtual status_t releaseBuffer(int slot, uint64_t frameNumber, + const sp<Fence>& releaseFence) override; +#else virtual status_t releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence, EGLDisplay display, EGLSyncKHR fence); - +#endif // connect connects a consumer to the BufferQueue. Only one // consumer may be connected, and when that consumer disconnects the // BufferQueue is placed into the "abandoned" state, causing most @@ -122,7 +122,10 @@ public: // setMaxAcquiredBufferCount sets the maximum number of buffers that can // be acquired by the consumer at one time (default 1). This call will // fail if a producer is connected to the BufferQueue. - virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers); + virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) override; + virtual status_t setMaxAcquiredBufferCount( + int maxAcquiredBuffers, + std::optional<OnBufferReleasedCallback> onBuffersReleasedCallback) override; // setConsumerName sets the name used in logging status_t setConsumerName(const String8& name) override; @@ -167,6 +170,7 @@ public: // dump our state in a String status_t dumpState(const String8& prefix, String8* outResult) const override; +#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) // Functions required for backwards compatibility. // These will be modified/renamed in IGraphicBufferConsumer and will be // removed from this class at that time. See b/13306289. @@ -176,6 +180,7 @@ public: const sp<Fence>& releaseFence) { return releaseBuffer(buf, frameNumber, releaseFence, display, fence); } +#endif virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { diff --git a/libs/gui/include/gui/Choreographer.h b/libs/gui/include/gui/Choreographer.h index a93ba14c57..5862967d4a 100644 --- a/libs/gui/include/gui/Choreographer.h +++ b/libs/gui/include/gui/Choreographer.h @@ -103,7 +103,7 @@ public: virtual void handleMessage(const Message& message) override; static void initJVM(JNIEnv* env); - static Choreographer* getForThread(); + static sp<Choreographer> getForThread(); static void signalRefreshRateCallbacks(nsecs_t vsyncPeriod) EXCLUDES(gChoreographers.lock); static int64_t getStartTimeNanosForVsyncId(AVsyncId vsyncId) EXCLUDES(gChoreographers.lock); virtual ~Choreographer() override EXCLUDES(gChoreographers.lock); diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h index 5cd19c1583..d2215ef7e6 100644 --- a/libs/gui/include/gui/ConsumerBase.h +++ b/libs/gui/include/gui/ConsumerBase.h @@ -98,6 +98,8 @@ public: status_t detachBuffer(const sp<GraphicBuffer>& buffer); #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) + status_t addReleaseFence(const sp<GraphicBuffer> buffer, const sp<Fence>& fence); + // See IGraphicBufferConsumer::setDefaultBufferSize status_t setDefaultBufferSize(uint32_t width, uint32_t height); @@ -121,9 +123,7 @@ public: // See IGraphicBufferConsumer::setMaxAcquiredBufferCount status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers); -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) status_t setConsumerIsProtected(bool isProtected); -#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) // See IGraphicBufferConsumer::getSidebandStream sp<NativeHandle> getSidebandStream() const; @@ -139,7 +139,8 @@ private: ConsumerBase(const ConsumerBase&); void operator=(const ConsumerBase&); - void initialize(bool controlledByApp); + // Requires `this` to be sp/wp so must not be called from ctor. + void initialize(); protected: // ConsumerBase constructs a new ConsumerBase object to consume image @@ -190,6 +191,8 @@ protected: #endif virtual int getSlotForBufferLocked(const sp<GraphicBuffer>& buffer); + virtual void onBuffersReleasedLocked(); + virtual status_t detachBufferLocked(int slotIndex); // freeBufferLocked frees up the given buffer slot. If the slot has been @@ -245,9 +248,16 @@ protected: // must take place when a buffer is released back to the BufferQueue. If // it is overridden the derived class's implementation must call // ConsumerBase::releaseBufferLocked. +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + virtual status_t releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer); +#else virtual status_t releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer, EGLDisplay display = EGL_NO_DISPLAY, EGLSyncKHR eglFence = EGL_NO_SYNC_KHR); +#endif + // Required to complete initialization, so `final` lest overrides forget to + // delegate. + void onFirstRef() override final; // returns true iff the slot still has the graphicBuffer in it. bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer); @@ -324,6 +334,8 @@ protected: // releaseBufferLocked. sp<Fence> mPrevFinalReleaseFence; + const bool mIsControlledByApp; + // mMutex is the mutex used to prevent concurrent access to the member // variables of ConsumerBase objects. It must be locked whenever the // member variables are accessed or when any of the *Locked methods are diff --git a/libs/gui/include/gui/CpuConsumer.h b/libs/gui/include/gui/CpuConsumer.h index 2bba61bbe8..995cdfb53d 100644 --- a/libs/gui/include/gui/CpuConsumer.h +++ b/libs/gui/include/gui/CpuConsumer.h @@ -31,6 +31,7 @@ namespace android { class BufferQueue; class GraphicBuffer; class String8; +class Surface; /** * CpuConsumer is a BufferQueue consumer endpoint that allows direct CPU @@ -92,6 +93,13 @@ class CpuConsumer : public ConsumerBase // Create a new CPU consumer. The maxLockedBuffers parameter specifies // how many buffers can be locked for user access at the same time. + static std::tuple<sp<CpuConsumer>, sp<Surface>> create(size_t maxLockedBuffers, + bool controlledByApp = false, + bool isConsumerSurfaceFlinger = false); + static sp<CpuConsumer> create(const sp<IGraphicBufferConsumer>& bq, size_t maxLockedBuffers, + bool controlledByApp = false) + __attribute((deprecated("Prefer ctors that create their own surface and consumer."))); + #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) CpuConsumer(size_t maxLockedBuffers, bool controlledByApp = false, bool isConsumerSurfaceFlinger = false); @@ -100,8 +108,8 @@ class CpuConsumer : public ConsumerBase bool controlledByApp = false) __attribute((deprecated("Prefer ctors that create their own surface and consumer."))); #else - CpuConsumer(const sp<IGraphicBufferConsumer>& bq, - size_t maxLockedBuffers, bool controlledByApp = false); + CpuConsumer(const sp<IGraphicBufferConsumer>& bq, size_t maxLockedBuffers, + bool controlledByApp = false); #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) // Gets the next graphics buffer from the producer and locks it for CPU use, diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h index ab6a6b78f7..f51390a0d8 100644 --- a/libs/gui/include/gui/DisplayEventReceiver.h +++ b/libs/gui/include/gui/DisplayEventReceiver.h @@ -55,20 +55,20 @@ static inline constexpr uint32_t fourcc(char c1, char c2, char c3, char c4) { static_cast<uint32_t>(c4); } +enum class DisplayEventType : uint32_t { + DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'), + DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'), + DISPLAY_EVENT_MODE_CHANGE = fourcc('m', 'o', 'd', 'e'), + DISPLAY_EVENT_MODE_REJECTION = fourcc('r', 'e', 'j', 'e'), + DISPLAY_EVENT_NULL = fourcc('n', 'u', 'l', 'l'), + DISPLAY_EVENT_FRAME_RATE_OVERRIDE = fourcc('r', 'a', 't', 'e'), + DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH = fourcc('f', 'l', 's', 'h'), + DISPLAY_EVENT_HDCP_LEVELS_CHANGE = fourcc('h', 'd', 'c', 'p'), +}; + // ---------------------------------------------------------------------------- class DisplayEventReceiver { public: - enum { - DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'), - DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'), - DISPLAY_EVENT_MODE_CHANGE = fourcc('m', 'o', 'd', 'e'), - DISPLAY_EVENT_MODE_REJECTION = fourcc('r', 'e', 'j', 'e'), - DISPLAY_EVENT_NULL = fourcc('n', 'u', 'l', 'l'), - DISPLAY_EVENT_FRAME_RATE_OVERRIDE = fourcc('r', 'a', 't', 'e'), - DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH = fourcc('f', 'l', 's', 'h'), - DISPLAY_EVENT_HDCP_LEVELS_CHANGE = fourcc('h', 'd', 'c', 'p'), - }; - struct Event { // We add __attribute__((aligned(8))) for nsecs_t fields because // we need to make sure all fields are aligned the same with x86 @@ -77,7 +77,7 @@ public: // https://en.wikipedia.org/wiki/Data_structure_alignment struct Header { - uint32_t type; + DisplayEventType type; PhysicalDisplayId displayId __attribute__((aligned(8))); nsecs_t timestamp __attribute__((aligned(8))); }; diff --git a/libs/gui/include/gui/DisplayLuts.h b/libs/gui/include/gui/DisplayLuts.h index ab86ac4af8..187381c4ae 100644 --- a/libs/gui/include/gui/DisplayLuts.h +++ b/libs/gui/include/gui/DisplayLuts.h @@ -18,6 +18,10 @@ #include <android-base/unique_fd.h> #include <binder/Parcel.h> #include <binder/Parcelable.h> +#include <cutils/ashmem.h> +#include <sys/mman.h> +#include <algorithm> +#include <ostream> #include <vector> namespace android::gui { @@ -62,4 +66,99 @@ private: base::unique_fd fd; }; // struct DisplayLuts +static inline void PrintTo(const std::vector<int32_t>& offsets, ::std::ostream* os) { + *os << "\n .offsets = {"; + for (size_t i = 0; i < offsets.size(); i++) { + *os << offsets[i]; + if (i != offsets.size() - 1) { + *os << ", "; + } + } + *os << "}"; +} + +static inline void PrintTo(const std::vector<DisplayLuts::Entry>& entries, ::std::ostream* os) { + *os << "\n .lutProperties = {\n"; + for (auto& [dimension, size, samplingKey] : entries) { + *os << " Entry{" + << "dimension: " << dimension << ", size: " << size << ", samplingKey: " << samplingKey + << "}\n"; + } + *os << " }"; +} + +static constexpr size_t kMaxPrintCount = 100; + +static inline void PrintTo(const std::vector<float>& buffer, size_t offset, int32_t dimension, + size_t size, ::std::ostream* os) { + size_t range = std::min(size, kMaxPrintCount); + *os << "{"; + if (dimension == 1) { + for (size_t i = 0; i < range; i++) { + *os << buffer[offset + i]; + if (i != range - 1) { + *os << ", "; + } + } + } else { + *os << "\n {R channel:"; + for (size_t i = 0; i < range; i++) { + *os << buffer[offset + i]; + if (i != range - 1) { + *os << ", "; + } + } + *os << "}\n {G channel:"; + for (size_t i = 0; i < range; i++) { + *os << buffer[offset + size + i]; + if (i != range - 1) { + *os << ", "; + } + } + *os << "}\n {B channel:"; + for (size_t i = 0; i < range; i++) { + *os << buffer[offset + 2 * size + i]; + if (i != range - 1) { + *os << ", "; + } + } + } + *os << "}"; +} + +static inline void PrintTo(const std::shared_ptr<DisplayLuts> luts, ::std::ostream* os) { + *os << "gui::DisplayLuts {"; + auto& fd = luts->getLutFileDescriptor(); + *os << "\n .pfd = " << fd.get(); + if (fd.ok()) { + PrintTo(luts->offsets, os); + PrintTo(luts->lutProperties, os); + // decode luts + int32_t fullLength = luts->offsets[luts->offsets.size() - 1]; + if (luts->lutProperties[luts->offsets.size() - 1].dimension == 1) { + fullLength += luts->lutProperties[luts->offsets.size() - 1].size; + } else { + fullLength += (luts->lutProperties[luts->offsets.size() - 1].size * + luts->lutProperties[luts->offsets.size() - 1].size * + luts->lutProperties[luts->offsets.size() - 1].size * 3); + } + size_t bufferSize = static_cast<size_t>(fullLength) * sizeof(float); + float* ptr = (float*)mmap(NULL, bufferSize, PROT_READ, MAP_SHARED, fd.get(), 0); + if (ptr == MAP_FAILED) { + *os << "\n .bufferdata cannot mmap!"; + return; + } + std::vector<float> buffers(ptr, ptr + fullLength); + munmap(ptr, bufferSize); + + *os << "\n .bufferdata = "; + for (size_t i = 0; i < luts->offsets.size(); i++) { + PrintTo(buffers, static_cast<size_t>(luts->offsets[i]), + luts->lutProperties[i].dimension, + static_cast<size_t>(luts->lutProperties[i].size), os); + } + } + *os << "\n }"; +} + } // namespace android::gui
\ No newline at end of file diff --git a/libs/gui/include/gui/GLConsumer.h b/libs/gui/include/gui/GLConsumer.h index 30cbfa2f9f..254d8ac79c 100644 --- a/libs/gui/include/gui/GLConsumer.h +++ b/libs/gui/include/gui/GLConsumer.h @@ -83,6 +83,20 @@ public: // If the constructor without the tex parameter is used, the GLConsumer is // created in a detached state, and attachToContext must be called before // calls to updateTexImage. + static std::tuple<sp<GLConsumer>, sp<Surface>> create(uint32_t tex, uint32_t textureTarget, + bool useFenceSync, + bool isControlledByApp); + static std::tuple<sp<GLConsumer>, sp<Surface>> create(uint32_t textureTarget, bool useFenceSync, + bool isControlledByApp); + static sp<GLConsumer> create(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, + uint32_t textureTarget, bool useFenceSync, bool isControlledByApp) + __attribute((deprecated( + "Prefer create functions that create their own surface and consumer."))); + static sp<GLConsumer> create(const sp<IGraphicBufferConsumer>& bq, uint32_t textureTarget, + bool useFenceSync, bool isControlledByApp) + __attribute((deprecated( + "Prefer create functions that create their own surface and consumer."))); + #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) GLConsumer(uint32_t tex, uint32_t textureTarget, bool useFenceSync, bool isControlledByApp); @@ -271,6 +285,7 @@ protected: #endif // releaseBufferLocked overrides the ConsumerBase method to update the // mEglSlots array in addition to the ConsumerBase. +#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) virtual status_t releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer, EGLDisplay display = EGL_NO_DISPLAY, EGLSyncKHR eglFence = EGL_NO_SYNC_KHR) override; @@ -279,16 +294,14 @@ protected: const sp<GraphicBuffer> graphicBuffer, EGLSyncKHR eglFence) { return releaseBufferLocked(slot, graphicBuffer, mEglDisplay, eglFence); } +#endif struct PendingRelease { - PendingRelease() : isPending(false), currentTexture(-1), - graphicBuffer(), display(nullptr), fence(nullptr) {} + PendingRelease() : isPending(false), currentTexture(-1), graphicBuffer() {} bool isPending; int currentTexture; sp<GraphicBuffer> graphicBuffer; - EGLDisplay display; - EGLSyncKHR fence; }; // This releases the buffer in the slot referenced by mCurrentTexture, @@ -468,16 +481,18 @@ private: // EGLSlot contains the information and object references that // GLConsumer maintains about a BufferQueue buffer slot. struct EglSlot { +#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) EglSlot() : mEglFence(EGL_NO_SYNC_KHR) {} - +#endif // mEglImage is the EGLImage created from mGraphicBuffer. sp<EglImage> mEglImage; - +#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) // mFence is the EGL sync object that must signal before the buffer // associated with this buffer slot may be dequeued. It is initialized // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based // on a compile-time option) set to a new sync object in updateTexImage. EGLSyncKHR mEglFence; +#endif }; // mEglDisplay is the EGLDisplay with which this GLConsumer is currently diff --git a/libs/gui/include/gui/IConsumerListener.h b/libs/gui/include/gui/IConsumerListener.h index 1695aae876..95e66c778e 100644 --- a/libs/gui/include/gui/IConsumerListener.h +++ b/libs/gui/include/gui/IConsumerListener.h @@ -16,9 +16,6 @@ #pragma once -#include <binder/IInterface.h> -#include <binder/SafeInterface.h> - #include <utils/Errors.h> #include <utils/RefBase.h> @@ -110,25 +107,6 @@ public: #endif }; -#ifndef NO_BINDER -class IConsumerListener : public ConsumerListener, public IInterface { -public: - DECLARE_META_INTERFACE(ConsumerListener) -}; - -class BnConsumerListener : public SafeBnInterface<IConsumerListener> { -public: - BnConsumerListener() : SafeBnInterface<IConsumerListener>("BnConsumerListener") {} - - status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags = 0) override; -}; - -#else -class IConsumerListener : public ConsumerListener { -}; -class BnConsumerListener : public IConsumerListener { -}; -#endif +class IConsumerListener : public ConsumerListener {}; } // namespace android diff --git a/libs/gui/include/gui/IGraphicBufferConsumer.h b/libs/gui/include/gui/IGraphicBufferConsumer.h index 56eb291335..8066b070fb 100644 --- a/libs/gui/include/gui/IGraphicBufferConsumer.h +++ b/libs/gui/include/gui/IGraphicBufferConsumer.h @@ -40,15 +40,8 @@ class NativeHandle; /* * See IGraphicBufferProducer for details on SLOT_COUNT. */ -#ifndef NO_BINDER -class IGraphicBufferConsumer : public IInterface { -public: - DECLARE_META_INTERFACE(GraphicBufferConsumer) -#else class IGraphicBufferConsumer : public RefBase { public: -#endif - enum { // Returned by releaseBuffer, after which the consumer must free any references to the // just-released buffer that it might have. @@ -139,12 +132,17 @@ public: // * the buffer slot was invalid // * the fence was NULL // * the buffer slot specified is not in the acquired state +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + virtual status_t releaseBuffer(int buf, uint64_t frameNumber, + const sp<Fence>& releaseFence) = 0; +#else virtual status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence, const sp<Fence>& releaseFence) = 0; status_t releaseBuffer(int buf, uint64_t frameNumber, const sp<Fence>& releaseFence) { return releaseBuffer(buf, frameNumber, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence); } +#endif // consumerConnect connects a consumer to the BufferQueue. Only one consumer may be connected, // and when that consumer disconnects the BufferQueue is placed into the "abandoned" state, @@ -245,6 +243,9 @@ public: // maxAcquiredBuffers must be (inclusive) between 1 and MAX_MAX_ACQUIRED_BUFFERS. It also cannot // cause the maxBufferCount value to be exceeded. // + // If called with onBuffersReleasedCallback, that call back will be called in lieu of + // IConsumerListener::onBuffersReleased. + // // Return of a value other than NO_ERROR means an error has occurred: // * NO_INIT - the BufferQueue has been abandoned // * BAD_VALUE - one of the below conditions occurred: @@ -255,6 +256,11 @@ public: // * INVALID_OPERATION - attempting to call this after a producer connected. virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) = 0; + using OnBufferReleasedCallback = std::function<void(void)>; + virtual status_t setMaxAcquiredBufferCount( + int maxAcquiredBuffers, + std::optional<OnBufferReleasedCallback> onBuffersReleasedCallback) = 0; + // setConsumerName sets the name used in logging virtual status_t setConsumerName(const String8& name) = 0; @@ -317,18 +323,4 @@ public: } }; -#ifndef NO_BINDER -class BnGraphicBufferConsumer : public SafeBnInterface<IGraphicBufferConsumer> { -public: - BnGraphicBufferConsumer() - : SafeBnInterface<IGraphicBufferConsumer>("BnGraphicBufferConsumer") {} - - status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags = 0) override; -}; -#else -class BnGraphicBufferConsumer : public IGraphicBufferConsumer { -}; -#endif - } // namespace android diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 9a422fd808..de553aef72 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -65,6 +65,7 @@ struct DisplayState; struct InputWindowCommands; class HdrCapabilities; class Rect; +class TransactionState; using gui::FrameTimelineInfo; using gui::IDisplayEventConnection; @@ -105,13 +106,7 @@ public: }; /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ - virtual status_t setTransactionState( - const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, - Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, - bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffer, - bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, - uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) = 0; + virtual status_t setTransactionState(TransactionState&& state) = 0; }; // ---------------------------------------------------------------------------- diff --git a/libs/gui/include/gui/InputTransferToken.h b/libs/gui/include/gui/InputTransferToken.h index 6530b5069a..b83f24562b 100644 --- a/libs/gui/include/gui/InputTransferToken.h +++ b/libs/gui/include/gui/InputTransferToken.h @@ -25,7 +25,7 @@ namespace android { struct InputTransferToken : public RefBase, Parcelable { public: - InputTransferToken() { mToken = new BBinder(); } + InputTransferToken() { mToken = sp<BBinder>::make(); } InputTransferToken(const sp<IBinder>& token) { mToken = token; } @@ -39,15 +39,9 @@ public: return NO_ERROR; }; + bool operator==(const InputTransferToken& other) const { return mToken == other.mToken; } + sp<IBinder> mToken; }; -static inline bool operator==(const sp<InputTransferToken>& token1, - const sp<InputTransferToken>& token2) { - if (token1.get() == token2.get()) { - return true; - } - return token1->mToken == token2->mToken; -} - -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/libs/gui/include/gui/LayerMetadata.h b/libs/gui/include/gui/LayerMetadata.h index 7ee291df4c..6381db228b 100644 --- a/libs/gui/include/gui/LayerMetadata.h +++ b/libs/gui/include/gui/LayerMetadata.h @@ -44,6 +44,10 @@ struct LayerMetadata : public Parcelable { LayerMetadata& operator=(const LayerMetadata& other); LayerMetadata& operator=(LayerMetadata&& other); + // Note: `default` is not feasible because Parcelable does not provide ==. + bool operator==(const LayerMetadata& rhs) const { return mMap == rhs.mMap; } + bool operator!=(const LayerMetadata&) const = default; + // Merges other into this LayerMetadata. If eraseEmpty is true, any entries in // in this whose keys are paired with empty values in other will be erased. bool merge(const LayerMetadata& other, bool eraseEmpty = false); diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 64f191b867..369d3d136a 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -17,9 +17,9 @@ #ifndef ANDROID_SF_LAYER_STATE_H #define ANDROID_SF_LAYER_STATE_H - #include <stdint.h> #include <sys/types.h> +#include <span> #include <android/gui/DisplayCaptureArgs.h> #include <android/gui/IWindowInfosReportedListener.h> @@ -69,21 +69,39 @@ struct client_cache_t { uint64_t id; bool operator==(const client_cache_t& other) const { return id == other.id; } + bool operator!=(const client_cache_t&) const = default; bool isValid() const { return token != nullptr; } }; class TrustedPresentationListener : public Parcelable { public: - sp<ITransactionCompletedListener> callbackInterface; - int callbackId = -1; + struct State { + sp<ITransactionCompletedListener> callbackInterface; + int callbackId = -1; + bool operator==(const State&) const = default; + bool operator!=(const State&) const = default; + }; void invoke(bool presentedWithinThresholds) { - callbackInterface->onTrustedPresentationChanged(callbackId, presentedWithinThresholds); + mState.callbackInterface->onTrustedPresentationChanged(mState.callbackId, + presentedWithinThresholds); + } + void configure(State&& state) { mState = std::move(state); } + const sp<ITransactionCompletedListener>& getCallback() { return mState.callbackInterface; } + void clear() { + mState.callbackInterface = nullptr; + mState.callbackId = -1; } status_t writeToParcel(Parcel* parcel) const; status_t readFromParcel(const Parcel* parcel); + + bool operator==(const TrustedPresentationListener& rhs) const { return mState == rhs.mState; } + bool operator!=(const TrustedPresentationListener&) const = default; + +private: + State mState; }; class BufferData : public Parcelable { @@ -231,6 +249,7 @@ struct layer_state_t { eBufferReleaseChannelChanged = 0x40000'00000000, ePictureProfileHandleChanged = 0x80000'00000000, eAppContentPriorityChanged = 0x100000'00000000, + eClientDrawnCornerRadiusChanged = 0x200000'00000000, }; layer_state_t(); @@ -251,9 +270,9 @@ struct layer_state_t { // Geometry updates. static constexpr uint64_t GEOMETRY_CHANGES = layer_state_t::eBufferCropChanged | layer_state_t::eBufferTransformChanged | layer_state_t::eCornerRadiusChanged | - layer_state_t::eCropChanged | layer_state_t::eDestinationFrameChanged | - layer_state_t::eMatrixChanged | layer_state_t::ePositionChanged | - layer_state_t::eTransformToDisplayInverseChanged | + layer_state_t::eClientDrawnCornerRadiusChanged | layer_state_t::eCropChanged | + layer_state_t::eDestinationFrameChanged | layer_state_t::eMatrixChanged | + layer_state_t::ePositionChanged | layer_state_t::eTransformToDisplayInverseChanged | layer_state_t::eTransparentRegionChanged | layer_state_t::eEdgeExtensionChanged; // Buffer and related updates. @@ -274,8 +293,8 @@ struct layer_state_t { layer_state_t::eColorSpaceAgnosticChanged | layer_state_t::eColorTransformChanged | layer_state_t::eCornerRadiusChanged | layer_state_t::eDimmingEnabledChanged | layer_state_t::eHdrMetadataChanged | layer_state_t::eShadowRadiusChanged | - layer_state_t::eStretchChanged | layer_state_t::ePictureProfileHandleChanged | - layer_state_t::eAppContentPriorityChanged; + layer_state_t::eStretchChanged | + layer_state_t::ePictureProfileHandleChanged | layer_state_t::eAppContentPriorityChanged; // Changes which invalidates the layer's visible region in CE. static constexpr uint64_t CONTENT_DIRTY = layer_state_t::CONTENT_CHANGES | @@ -300,9 +319,40 @@ struct layer_state_t { static constexpr uint64_t VISIBLE_REGION_CHANGES = layer_state_t::GEOMETRY_CHANGES | layer_state_t::HIERARCHY_CHANGES | layer_state_t::eAlphaChanged; + // Changes that force GPU composition. + static constexpr uint64_t COMPOSITION_EFFECTS = layer_state_t::eBackgroundBlurRadiusChanged | + layer_state_t::eBlurRegionsChanged | layer_state_t::eCornerRadiusChanged | + layer_state_t::eShadowRadiusChanged | layer_state_t::eStretchChanged; + bool hasValidBuffer() const; void sanitize(int32_t permissions); + void updateTransparentRegion(const Region& transparentRegion); + const Region& getTransparentRegion() const { return mNotDefCmpState.transparentRegion; } + void updateSurfaceDamageRegion(const Region& surfaceDamageRegion); + const Region& getSurfaceDamageRegion() const { return mNotDefCmpState.surfaceDamageRegion; } + // Do not update state flags. Used to set up test state. + void setSurfaceDamageRegion(Region&& surfaceDamageRegion) { + mNotDefCmpState.surfaceDamageRegion = std::move(surfaceDamageRegion); + } + void updateRelativeLayer(const sp<SurfaceControl>& relativeTo, int32_t z); + void updateParentLayer(const sp<SurfaceControl>& newParent); + void updateInputWindowInfo(sp<gui::WindowInfoHandle>&& info); + const gui::WindowInfo& getWindowInfo() const { + return *mNotDefCmpState.windowInfoHandle->getInfo(); + } + gui::WindowInfo* editWindowInfo() { return mNotDefCmpState.windowInfoHandle->editInfo(); } + + const sp<SurfaceControl>& getParentSurfaceControlForChild() const { + return mNotDefCmpState.parentSurfaceControlForChild; + } + const sp<SurfaceControl>& getRelativeLayerSurfaceControl() const { + return mNotDefCmpState.relativeLayerSurfaceControl; + } + + bool operator==(const layer_state_t&) const = default; + bool operator!=(const layer_state_t&) const = default; + struct matrix22_t { float dsdx{0}; float dtdx{0}; @@ -328,30 +378,23 @@ struct layer_state_t { uint8_t reserved; matrix22_t matrix; float cornerRadius; + float clientDrawnCornerRadius; uint32_t backgroundBlurRadius; - sp<SurfaceControl> relativeLayerSurfaceControl; - - sp<SurfaceControl> parentSurfaceControlForChild; - half4 color; // non POD must be last. see write/read - Region transparentRegion; uint32_t bufferTransform; bool transformToDisplayInverse; FloatRect crop; std::shared_ptr<BufferData> bufferData = nullptr; ui::Dataspace dataspace; HdrMetadata hdrMetadata; - Region surfaceDamageRegion; int32_t api; sp<NativeHandle> sidebandStream; mat4 colorTransform; std::vector<BlurRegion> blurRegions; - sp<gui::WindowInfoHandle> windowInfoHandle = sp<gui::WindowInfoHandle>::make(); - LayerMetadata metadata; // The following refer to the alpha, and dataspace, respectively of @@ -437,6 +480,18 @@ struct layer_state_t { std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> bufferReleaseChannel; std::shared_ptr<gui::DisplayLuts> luts; + +protected: + struct NotDefaultComparableState { + Region transparentRegion; + Region surfaceDamageRegion; + sp<gui::WindowInfoHandle> windowInfoHandle = sp<gui::WindowInfoHandle>::make(); + sp<SurfaceControl> relativeLayerSurfaceControl; + sp<SurfaceControl> parentSurfaceControlForChild; + + bool operator==(const NotDefaultComparableState& rhs) const; + bool operator!=(const NotDefaultComparableState& rhs) const = default; + } mNotDefCmpState; }; class ComposerState { @@ -444,6 +499,9 @@ public: layer_state_t state; status_t write(Parcel& output) const; status_t read(const Parcel& input); + + bool operator==(const ComposerState&) const = default; + bool operator!=(const ComposerState&) const = default; }; struct DisplayState { @@ -495,28 +553,49 @@ struct DisplayState { Rect layerStackSpaceRect = Rect::EMPTY_RECT; Rect orientedDisplaySpaceRect = Rect::EMPTY_RECT; - // Exclusive to virtual displays: The sink surface into which the virtual display is rendered, - // and an optional resolution that overrides its default dimensions. - sp<IGraphicBufferProducer> surface; + // For physical displays, this is the resolution, which must match the active display mode. To + // change the resolution, the client must first call SurfaceControl.setDesiredDisplayModeSpecs + // with the new DesiredDisplayModeSpecs#defaultMode, then commit the matching width and height. + // + // For virtual displays, this is an optional resolution that overrides its default dimensions. + // uint32_t width = 0; uint32_t height = 0; + // For virtual displays, this is the sink surface into which the virtual display is rendered. + sp<IGraphicBufferProducer> surface; + status_t write(Parcel& output) const; status_t read(const Parcel& input); + + bool operator==(const DisplayState&) const = default; + bool operator!=(const DisplayState&) const = default; }; struct InputWindowCommands { - std::vector<gui::FocusRequest> focusRequests; - std::unordered_set<sp<gui::IWindowInfosReportedListener>, - SpHash<gui::IWindowInfosReportedListener>> - windowInfosReportedListeners; - + using Listener = gui::IWindowInfosReportedListener; + using ListenerSet = std::unordered_set<sp<Listener>, SpHash<Listener>>; // Merges the passed in commands and returns true if there were any changes. bool merge(const InputWindowCommands& other); bool empty() const; void clear(); + void addFocusRequest(const gui::FocusRequest& request) { focusRequests.push_back(request); } + void addWindowInfosReportedListener(const sp<Listener>& listener) { + windowInfosReportedListeners.insert(listener); + } + ListenerSet&& releaseListeners() { return std::move(windowInfosReportedListeners); } + status_t write(Parcel& output) const; status_t read(const Parcel& input); + + std::span<const gui::FocusRequest> getFocusRequests() const { return focusRequests; } + const ListenerSet& getListeners() const { return windowInfosReportedListeners; } + bool operator==(const InputWindowCommands&) const = default; + bool operator!=(const InputWindowCommands&) const = default; + +private: + std::vector<gui::FocusRequest> focusRequests; + ListenerSet windowInfosReportedListeners; }; static inline int compare_type(const ComposerState& lhs, const ComposerState& rhs) { diff --git a/libs/gui/include/gui/StreamSplitter.h b/libs/gui/include/gui/StreamSplitter.h index b4eef292c1..8176f753c3 100644 --- a/libs/gui/include/gui/StreamSplitter.h +++ b/libs/gui/include/gui/StreamSplitter.h @@ -37,7 +37,7 @@ class IGraphicBufferProducer; // BufferQueue, where each buffer queued to the input is available to be // acquired by each of the outputs, and is able to be dequeued by the input // again only once all of the outputs have released it. -class StreamSplitter : public BnConsumerListener { +class StreamSplitter : public IConsumerListener { public: // createSplitter creates a new splitter, outSplitter, using inputQueue as // the input BufferQueue. Output BufferQueues must be added using addOutput @@ -153,6 +153,8 @@ private: size_t mReleaseCount; }; + friend class sp<StreamSplitter>; + // Only called from createSplitter explicit StreamSplitter(const sp<IGraphicBufferConsumer>& inputQueue); diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 0f66c8b492..15e3341ca2 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -52,6 +52,7 @@ #include <gui/ITransactionCompletedListener.h> #include <gui/LayerState.h> #include <gui/SurfaceControl.h> +#include <gui/TransactionState.h> #include <gui/WindowInfosListenerReporter.h> #include <math/vec3.h> @@ -345,8 +346,6 @@ public: static std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport> getDisplayDecorationSupport(const sp<IBinder>& displayToken); - static bool flagEdgeExtensionEffectUseShader(); - /** * Returns how many picture profiles are supported by the display. * @@ -396,6 +395,7 @@ public: static const std::string kEmpty; static sp<IBinder> createVirtualDisplay(const std::string& displayName, bool isSecure, + bool optimizeForPower = true, const std::string& uniqueId = kEmpty, float requestedRefreshRate = 0); @@ -448,59 +448,11 @@ public: static sp<IBinder> sApplyToken; static std::mutex sApplyTokenMutex; void releaseBufferIfOverwriting(const layer_state_t& state); - static void mergeFrameTimelineInfo(FrameTimelineInfo& t, const FrameTimelineInfo& other); // Tracks registered callbacks sp<TransactionCompletedListener> mTransactionCompletedListener = nullptr; - // Prints debug logs when enabled. - bool mLogCallPoints = false; - - protected: - std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> mComposerStates; - SortedVector<DisplayState> mDisplayStates; - std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash> - mListenerCallbacks; - std::vector<client_cache_t> mUncacheBuffers; - - // We keep track of the last MAX_MERGE_HISTORY_LENGTH merged transaction ids. - // Ordered most recently merged to least recently merged. - static const size_t MAX_MERGE_HISTORY_LENGTH = 10u; - std::vector<uint64_t> mMergedTransactionIds; - - uint64_t mId; - - bool mAnimation = false; - bool mEarlyWakeupStart = false; - bool mEarlyWakeupEnd = false; - - // Indicates that the Transaction may contain buffers that should be cached. The reason this - // is only a guess is that buffers can be removed before cache is called. This is only a - // hint that at some point a buffer was added to this transaction before apply was called. - bool mMayContainBuffer = false; - // mDesiredPresentTime is the time in nanoseconds that the client would like the transaction - // to be presented. When it is not possible to present at exactly that time, it will be - // presented after the time has passed. - // - // If the client didn't pass a desired presentation time, mDesiredPresentTime will be - // populated to the time setBuffer was called, and mIsAutoTimestamp will be set to true. - // - // Desired present times that are more than 1 second in the future may be ignored. - // When a desired present time has already passed, the transaction will be presented as soon - // as possible. - // - // Transactions from the same process are presented in the same order that they are applied. - // The desired present time does not affect this ordering. - int64_t mDesiredPresentTime = 0; - bool mIsAutoTimestamp = true; - - // The vsync id provided by Choreographer.getVsyncId and the input event id - FrameTimelineInfo mFrameTimelineInfo; - - // If not null, transactions will be queued up using this token otherwise a common token - // per process will be used. - sp<IBinder> mApplyToken = nullptr; + TransactionState mState; - InputWindowCommands mInputWindowCommands; int mStatus = NO_ERROR; layer_state_t* getLayerState(const sp<SurfaceControl>& sc); @@ -510,6 +462,11 @@ public: void registerSurfaceControlForCallback(const sp<SurfaceControl>& sc); void setReleaseBufferCallback(BufferData*, ReleaseBufferCallback); + protected: + // Accessed in tests. + std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash> + mListenerCallbacks; + public: Transaction(); virtual ~Transaction() = default; @@ -526,7 +483,7 @@ public: // Returns the current id of the transaction. // The id is updated every time the transaction is applied. - uint64_t getId(); + uint64_t getId() const; std::vector<uint64_t> getMergedTransactionIds(); @@ -567,6 +524,11 @@ public: Transaction& setCrop(const sp<SurfaceControl>& sc, const Rect& crop); Transaction& setCrop(const sp<SurfaceControl>& sc, const FloatRect& crop); Transaction& setCornerRadius(const sp<SurfaceControl>& sc, float cornerRadius); + // Sets the client drawn corner radius for the layer. If both a corner radius and a client + // radius are sent to SF, the client radius will be used. This indicates that the corner + // radius is drawn by the client and not SurfaceFlinger. + Transaction& setClientDrawnCornerRadius(const sp<SurfaceControl>& sc, + float clientDrawnCornerRadius); Transaction& setBackgroundBlurRadius(const sp<SurfaceControl>& sc, int backgroundBlurRadius); Transaction& setBlurRegions(const sp<SurfaceControl>& sc, @@ -618,7 +580,7 @@ public: Transaction& setExtendedRangeBrightness(const sp<SurfaceControl>& sc, float currentBufferRatio, float desiredRatio); Transaction& setDesiredHdrHeadroom(const sp<SurfaceControl>& sc, float desiredRatio); - Transaction& setLuts(const sp<SurfaceControl>& sc, const base::unique_fd& lutFd, + Transaction& setLuts(const sp<SurfaceControl>& sc, base::unique_fd&& lutFd, const std::vector<int32_t>& offsets, const std::vector<int32_t>& dimensions, const std::vector<int32_t>& sizes, diff --git a/libs/gui/include/gui/TransactionState.h b/libs/gui/include/gui/TransactionState.h new file mode 100644 index 0000000000..4358227dae --- /dev/null +++ b/libs/gui/include/gui/TransactionState.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <android/gui/FrameTimelineInfo.h> +#include <binder/Parcelable.h> +#include <gui/LayerState.h> + +namespace android { + +// Class to store all the transaction data and the parcelling logic +class TransactionState { +public: + explicit TransactionState() = default; + TransactionState(TransactionState const& other) = default; + status_t writeToParcel(Parcel* parcel) const; + status_t readFromParcel(const Parcel* parcel); + layer_state_t* getLayerState(const sp<SurfaceControl>& sc); + DisplayState& getDisplayState(const sp<IBinder>& token); + + // Returns the current id of the transaction. + // The id is updated every time the transaction is applied. + uint64_t getId() const { return mId; } + std::vector<uint64_t> getMergedTransactionIds() const { return mMergedTransactionIds; } + void enableDebugLogCallPoints() { mLogCallPoints = true; } + void merge(TransactionState&& other, + const std::function<void(layer_state_t&)>& onBufferOverwrite); + + // copied from FrameTimelineInfo::merge() + void mergeFrameTimelineInfo(const FrameTimelineInfo& other); + void clear(); + bool operator==(const TransactionState& rhs) const = default; + bool operator!=(const TransactionState& rhs) const = default; + + uint64_t mId = 0; + std::vector<uint64_t> mMergedTransactionIds; + uint32_t mFlags = 0; + // The vsync id provided by Choreographer.getVsyncId and the input event id + gui::FrameTimelineInfo mFrameTimelineInfo; + // mDesiredPresentTime is the time in nanoseconds that the client would like the transaction + // to be presented. When it is not possible to present at exactly that time, it will be + // presented after the time has passed. + // + // If the client didn't pass a desired presentation time, mDesiredPresentTime will be + // populated to the time setBuffer was called, and mIsAutoTimestamp will be set to true. + // + // Desired present times that are more than 1 second in the future may be ignored. + // When a desired present time has already passed, the transaction will be presented as soon + // as possible. + // + // Transactions from the same process are presented in the same order that they are applied. + // The desired present time does not affect this ordering. + int64_t mDesiredPresentTime = 0; + bool mIsAutoTimestamp = true; + // If not null, transactions will be queued up using this token otherwise a common token + // per process will be used. + sp<IBinder> mApplyToken; + // Indicates that the Transaction may contain buffers that should be cached. The reason this + // is only a guess is that buffers can be removed before cache is called. This is only a + // hint that at some point a buffer was added to this transaction before apply was called. + bool mMayContainBuffer = false; + // Prints debug logs when enabled. + bool mLogCallPoints = false; + + std::vector<DisplayState> mDisplayStates; + std::vector<ComposerState> mComposerStates; + InputWindowCommands mInputWindowCommands; + std::vector<client_cache_t> mUncacheBuffers; + // Note: mHasListenerCallbacks can be true even if mListenerCallbacks is + // empty. + bool mHasListenerCallbacks = false; + std::vector<ListenerCallbacks> mListenerCallbacks; + +private: + // We keep track of the last MAX_MERGE_HISTORY_LENGTH merged transaction ids. + // Ordered most recently merged to least recently merged. + static constexpr size_t MAX_MERGE_HISTORY_LENGTH = 10u; +}; + +}; // namespace android diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h index eb3be5588a..9ac49c0fb6 100644 --- a/libs/gui/include/gui/WindowInfo.h +++ b/libs/gui/include/gui/WindowInfo.h @@ -150,8 +150,6 @@ struct WindowInfo : public Parcelable { static_cast<uint32_t>(os::InputConfig::NOT_FOCUSABLE), NOT_TOUCHABLE = static_cast<uint32_t>(os::InputConfig::NOT_TOUCHABLE), - PREVENT_SPLITTING = - static_cast<uint32_t>(os::InputConfig::PREVENT_SPLITTING), DUPLICATE_TOUCH_TO_WALLPAPER = static_cast<uint32_t>(os::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER), IS_WALLPAPER = @@ -220,9 +218,14 @@ struct WindowInfo : public Parcelable { // An alpha of 1.0 means fully opaque and 0.0 means fully transparent. float alpha; - // Transform applied to individual windows. + // Transform applied to individual windows for input. + // Maps display coordinates to the window's input coordinate space. ui::Transform transform; + // Transform applied to get to the layer stack space of the cloned window for input. + // Maps display coordinates of the clone window to the layer stack space of the cloned window. + std::optional<ui::Transform> cloneLayerStackTransform; + /* * This is filled in by the WM relative to the frame and then translated * to absolute coordinates by SurfaceFlinger once the frame is computed. @@ -265,6 +268,7 @@ struct WindowInfo : public Parcelable { bool overlaps(const WindowInfo* other) const; bool operator==(const WindowInfo& inputChannel) const; + bool operator!=(const WindowInfo&) const = default; status_t writeToParcel(android::Parcel* parcel) const override; @@ -316,6 +320,9 @@ public: status_t readFromParcel(const android::Parcel* parcel); status_t writeToParcel(android::Parcel* parcel) const; + bool operator==(const WindowInfoHandle& rhs) const { return mInfo == rhs.mInfo; } + bool operator!=(const WindowInfoHandle&) const = default; + protected: virtual ~WindowInfoHandle(); diff --git a/libs/gui/include/gui/mock/GraphicBufferConsumer.h b/libs/gui/include/gui/mock/GraphicBufferConsumer.h index 98f24c2d44..18a7e12fa7 100644 --- a/libs/gui/include/gui/mock/GraphicBufferConsumer.h +++ b/libs/gui/include/gui/mock/GraphicBufferConsumer.h @@ -18,6 +18,7 @@ #include <gmock/gmock.h> +#include <com_android_graphics_libgui_flags.h> #include <gui/IGraphicBufferConsumer.h> #include <utils/RefBase.h> @@ -25,21 +26,28 @@ namespace android { namespace mock { -class GraphicBufferConsumer : public BnGraphicBufferConsumer, public virtual android::RefBase { +class GraphicBufferConsumer : public IGraphicBufferConsumer { public: GraphicBufferConsumer(); - ~GraphicBufferConsumer() override; + ~GraphicBufferConsumer(); MOCK_METHOD3(acquireBuffer, status_t(BufferItem*, nsecs_t, uint64_t)); MOCK_METHOD1(detachBuffer, status_t(int)); MOCK_METHOD2(attachBuffer, status_t(int*, const sp<GraphicBuffer>&)); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + MOCK_METHOD3(releaseBuffer, status_t(int, uint64_t, const sp<Fence>&)); +#else MOCK_METHOD5(releaseBuffer, status_t(int, uint64_t, EGLDisplay, EGLSyncKHR, const sp<Fence>&)); +#endif MOCK_METHOD2(consumerConnect, status_t(const sp<IConsumerListener>&, bool)); MOCK_METHOD0(consumerDisconnect, status_t()); + MOCK_METHOD1(allowUnlimitedSlots, status_t(bool)); MOCK_METHOD1(getReleasedBuffers, status_t(uint64_t*)); + MOCK_METHOD1(getReleasedBuffersExtended, status_t(std::vector<bool>*)); MOCK_METHOD2(setDefaultBufferSize, status_t(uint32_t, uint32_t)); MOCK_METHOD1(setMaxBufferCount, status_t(int)); MOCK_METHOD1(setMaxAcquiredBufferCount, status_t(int)); + MOCK_METHOD2(setMaxAcquiredBufferCount, status_t(int, std::optional<OnBufferReleasedCallback>)); MOCK_METHOD1(setConsumerName, status_t(const String8&)); MOCK_METHOD1(setDefaultBufferFormat, status_t(PixelFormat)); MOCK_METHOD1(setDefaultBufferDataSpace, status_t(android_dataspace)); diff --git a/libs/gui/libgui_flags.aconfig b/libs/gui/libgui_flags.aconfig index 6bf38c05f1..ce1bc9512c 100644 --- a/libs/gui/libgui_flags.aconfig +++ b/libs/gui/libgui_flags.aconfig @@ -77,14 +77,6 @@ flag { } # wb_stream_splitter flag { - name: "edge_extension_shader" - namespace: "windowing_frontend" - description: "Enable edge extension via shader" - bug: "322036393" - is_fixed_read_only: true -} # edge_extension_shader - -flag { name: "buffer_release_channel" namespace: "window_surfaces" description: "Enable BufferReleaseChannel to optimize buffer releases" @@ -139,3 +131,33 @@ flag { bug: "339705065" is_fixed_read_only: true } # bq_gl_fence_cleanup + +flag { + name: "wb_media_migration" + namespace: "core_graphics" + description: "Main flag for the warren buffers media migration." + bug: "340934031" + is_fixed_read_only: true +} # wb_media_migration + +flag { + name: "allocate_buffer_priority" + namespace: "wear_system_health" + description: "Boost priority for buffer allocation" + bug: "399701430" + metadata { + purpose: PURPOSE_BUGFIX + } + is_fixed_read_only: true +} # allocate_buffer_priority + +flag { + name: "bq_always_use_max_dequeued_buffer_count" + namespace: "core_graphics" + description: "BufferQueueProducer::dequeue's respects setMaxDequeuedBufferCount even before a buffer is dequeued." + bug: "399328309" + metadata { + purpose: PURPOSE_BUGFIX + } + is_fixed_read_only: true +} # bq_always_use_max_dequeued_buffer_count diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp index 87051a7aac..e20345dd1a 100644 --- a/libs/gui/tests/Android.bp +++ b/libs/gui/tests/Android.bp @@ -90,6 +90,7 @@ cc_test { "testserver/TestServerClient.cpp", "testserver/TestServerHost.cpp", "TextureRenderer.cpp", + "TransactionState_test.cpp", "VsyncEventData_test.cpp", "WindowInfo_test.cpp", ], diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index 53f4a36c42..b861c6d4b7 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -81,7 +81,9 @@ class TestBLASTBufferQueue : public BLASTBufferQueue { public: TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width, int height, int32_t format) - : BLASTBufferQueue(name, surface, width, height, format) {} + : BLASTBufferQueue(name) { + update(surface, width, height, format); + } void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence, const std::vector<SurfaceControlStats>& stats) override { @@ -112,8 +114,8 @@ private: class BLASTBufferQueueHelper { public: BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) { - mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width, - height, PIXEL_FORMAT_RGBA_8888); + mBlastBufferQueueAdapter = sp<TestBLASTBufferQueue>::make("TestBLASTBufferQueue", sc, width, + height, PIXEL_FORMAT_RGBA_8888); } void update(const sp<SurfaceControl>& sc, int width, int height) { diff --git a/libs/gui/tests/BufferItemConsumer_test.cpp b/libs/gui/tests/BufferItemConsumer_test.cpp index 6453885804..80eea267bf 100644 --- a/libs/gui/tests/BufferItemConsumer_test.cpp +++ b/libs/gui/tests/BufferItemConsumer_test.cpp @@ -24,6 +24,7 @@ #include <gui/Surface.h> #include <ui/BufferQueueDefs.h> #include <ui/GraphicBuffer.h> +#include <utils/Errors.h> #include <unordered_set> @@ -62,14 +63,15 @@ class BufferItemConsumerTest : public ::testing::Test { void SetUp() override { mBuffers.resize(BufferQueueDefs::NUM_BUFFER_SLOTS); - mBIC = new BufferItemConsumer(kUsage, kMaxLockedBuffers, true); + sp<Surface> surface; + std::tie(mBIC, surface) = BufferItemConsumer::create(kUsage, kMaxLockedBuffers, true); String8 name("BufferItemConsumer_Under_Test"); mBIC->setName(name); mBFL = new BufferFreedListener(this); mBIC->setBufferFreedListener(mBFL); sp<IProducerListener> producerListener = new TrackingProducerListener(this); - mProducer = mBIC->getSurface()->getIGraphicBufferProducer(); + mProducer = surface->getIGraphicBufferProducer(); IGraphicBufferProducer::QueueBufferOutput bufferOutput; ASSERT_EQ(NO_ERROR, mProducer->connect(producerListener, NATIVE_WINDOW_API_CPU, @@ -234,6 +236,38 @@ TEST_F(BufferItemConsumerTest, TriggerBufferFreed_DeleteBufferItemConsumer) { ASSERT_EQ(1, GetFreedBufferCount()); } +TEST_F(BufferItemConsumerTest, ResizeAcquireCount) { + EXPECT_EQ(OK, mBIC->setMaxAcquiredBufferCount(kMaxLockedBuffers + 1)); + EXPECT_EQ(OK, mBIC->setMaxAcquiredBufferCount(kMaxLockedBuffers + 2)); + EXPECT_EQ(OK, mBIC->setMaxAcquiredBufferCount(kMaxLockedBuffers - 1)); + EXPECT_EQ(OK, mBIC->setMaxAcquiredBufferCount(kMaxLockedBuffers - 2)); + EXPECT_EQ(OK, mBIC->setMaxAcquiredBufferCount(kMaxLockedBuffers + 1)); + EXPECT_EQ(OK, mBIC->setMaxAcquiredBufferCount(kMaxLockedBuffers - 1)); +} + +TEST_F(BufferItemConsumerTest, AttachBuffer) { + ASSERT_EQ(OK, mBIC->setMaxAcquiredBufferCount(1)); + + int slot; + DequeueBuffer(&slot); + QueueBuffer(slot); + AcquireBuffer(&slot); + + sp<GraphicBuffer> newBuffer1 = sp<GraphicBuffer>::make(kWidth, kHeight, kFormat, kUsage); + sp<GraphicBuffer> newBuffer2 = sp<GraphicBuffer>::make(kWidth, kHeight, kFormat, kUsage); + + // For some reason, you can attach an extra buffer? + // b/400973991 to investigate + EXPECT_EQ(OK, mBIC->attachBuffer(newBuffer1)); + EXPECT_EQ(INVALID_OPERATION, mBIC->attachBuffer(newBuffer2)); + + ReleaseBuffer(slot); + + EXPECT_EQ(OK, mBIC->attachBuffer(newBuffer2)); + EXPECT_EQ(OK, mBIC->releaseBuffer(newBuffer1, Fence::NO_FENCE)); + EXPECT_EQ(OK, mBIC->releaseBuffer(newBuffer2, Fence::NO_FENCE)); +} + #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) // Test that delete BufferItemConsumer triggers onBufferFreed. TEST_F(BufferItemConsumerTest, DetachBufferWithBuffer) { diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 77b4ae8623..cfbb2e7386 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -32,6 +32,7 @@ #include <ui/PictureProfileHandle.h> #include <android-base/properties.h> +#include <android-base/unique_fd.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> @@ -45,6 +46,7 @@ #include <gmock/gmock.h> #include <gtest/gtest.h> +#include <csignal> #include <future> #include <optional> #include <thread> @@ -65,6 +67,15 @@ class BufferQueueTest : public ::testing::Test { public: protected: + void TearDown() override { + std::vector<std::function<void()>> teardownFns; + teardownFns.swap(mTeardownFns); + + for (auto& fn : teardownFns) { + fn(); + } + } + void GetMinUndequeuedBufferCount(int* bufferCount) { ASSERT_TRUE(bufferCount != nullptr); ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, @@ -99,6 +110,7 @@ protected: sp<IGraphicBufferProducer> mProducer; sp<IGraphicBufferConsumer> mConsumer; + std::vector<std::function<void()>> mTeardownFns; }; static const uint32_t TEST_DATA = 0x12345678u; @@ -106,12 +118,14 @@ static const uint32_t TEST_DATA = 0x12345678u; // XXX: Tests that fork a process to hold the BufferQueue must run before tests // that use a local BufferQueue, or else Binder will get unhappy // -// In one instance this was a crash in the createBufferQueue where the -// binder call to create a buffer allocator apparently got garbage back. -// See b/36592665. +// TODO(b/392945118): In one instance this was a crash in the createBufferQueue +// where the binder call to create a buffer allocator apparently got garbage +// back. See b/36592665. TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) { const String16 PRODUCER_NAME = String16("BQTestProducer"); - const String16 CONSUMER_NAME = String16("BQTestConsumer"); + + base::unique_fd readfd, writefd; + ASSERT_TRUE(base::Pipe(&readfd, &writefd)); pid_t forkPid = fork(); ASSERT_NE(forkPid, -1); @@ -123,23 +137,51 @@ TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) { BufferQueue::createBufferQueue(&producer, &consumer); sp<IServiceManager> serviceManager = defaultServiceManager(); serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer)); - serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer)); + + class ChildConsumerListener : public IConsumerListener { + public: + ChildConsumerListener(const sp<IGraphicBufferConsumer>& consumer, + base::unique_fd&& writeFd) + : mConsumer(consumer), mWriteFd(std::move(writeFd)) {} + + virtual void onFrameAvailable(const BufferItem&) override { + BufferItem item; + ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); + + uint32_t* dataOut; + ASSERT_EQ(OK, + item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, + reinterpret_cast<void**>(&dataOut))); + ASSERT_EQ(*dataOut, TEST_DATA); + ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); + + bool isOk = true; + write(mWriteFd, &isOk, sizeof(bool)); + } + virtual void onBuffersReleased() override {} + virtual void onSidebandStreamChanged() override {} + + private: + sp<IGraphicBufferConsumer> mConsumer; + base::unique_fd mWriteFd; + }; + + sp<ChildConsumerListener> mc = + sp<ChildConsumerListener>::make(consumer, std::move(writefd)); + ASSERT_EQ(OK, consumer->consumerConnect(mc, false)); + ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); LOG_ALWAYS_FATAL("Shouldn't be here"); + } else { + mTeardownFns.emplace_back([forkPid]() { kill(forkPid, SIGTERM); }); } sp<IServiceManager> serviceManager = defaultServiceManager(); sp<IBinder> binderProducer = serviceManager->waitForService(PRODUCER_NAME); mProducer = interface_cast<IGraphicBufferProducer>(binderProducer); EXPECT_TRUE(mProducer != nullptr); - sp<IBinder> binderConsumer = - serviceManager->getService(CONSUMER_NAME); - mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer); - EXPECT_TRUE(mConsumer != nullptr); - sp<MockConsumer> mc(new MockConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false)); IGraphicBufferProducer::QueueBufferOutput output; ASSERT_EQ(OK, mProducer->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output)); @@ -163,14 +205,9 @@ TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) { NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - BufferItem item; - ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); - - uint32_t* dataOut; - ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, - reinterpret_cast<void**>(&dataOut))); - ASSERT_EQ(*dataOut, TEST_DATA); - ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); + bool isOk; + read(readfd, &isOk, sizeof(bool)); + ASSERT_TRUE(isOk); } TEST_F(BufferQueueTest, GetMaxBufferCountInQueueBufferOutput_Succeeds) { diff --git a/libs/gui/tests/Choreographer_test.cpp b/libs/gui/tests/Choreographer_test.cpp index 8db48d2eb0..314dea62d4 100644 --- a/libs/gui/tests/Choreographer_test.cpp +++ b/libs/gui/tests/Choreographer_test.cpp @@ -50,7 +50,7 @@ static void vsyncCallback(const AChoreographerFrameCallbackData* callbackData, v TEST_F(ChoreographerTest, InputCallbackBeforeAnimation) { sp<Looper> looper = Looper::prepare(0); - Choreographer* choreographer = Choreographer::getForThread(); + sp<Choreographer> choreographer = Choreographer::getForThread(); VsyncCallback animationCb; choreographer->postFrameCallbackDelayed(nullptr, nullptr, vsyncCallback, &animationCb, 0, CALLBACK_ANIMATION); @@ -83,4 +83,4 @@ TEST_F(ChoreographerTest, InputCallbackBeforeAnimation) { animationCb.frameTime.count()); } -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp index 9476930de3..482cfde6e9 100644 --- a/libs/gui/tests/CpuConsumer_test.cpp +++ b/libs/gui/tests/CpuConsumer_test.cpp @@ -66,10 +66,9 @@ protected: test_info->name(), params.width, params.height, params.maxLockedBuffers, params.format); - mCC = new CpuConsumer(params.maxLockedBuffers); + std::tie(mCC, mSTC) = CpuConsumer::create(params.maxLockedBuffers); String8 name("CpuConsumer_Under_Test"); mCC->setName(name); - mSTC = mCC->getSurface(); mANW = mSTC; } diff --git a/libs/gui/tests/DisconnectWaiter.h b/libs/gui/tests/DisconnectWaiter.h index 6e6915b299..3d5f63375d 100644 --- a/libs/gui/tests/DisconnectWaiter.h +++ b/libs/gui/tests/DisconnectWaiter.h @@ -29,7 +29,7 @@ namespace android { // no way to forward the events. This DisconnectWaiter will not let the // disconnect finish until finishDisconnect() is called. It will // also block until a disconnect is called -class DisconnectWaiter : public BnConsumerListener { +class DisconnectWaiter : public IConsumerListener { public: DisconnectWaiter () : mWaitForDisconnect(false), diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 06f00a4d74..cf05fd4ba5 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -85,6 +85,7 @@ sp<IInputFlinger> getInputFlinger() { // We use the top 10 layers as a way to haphazardly place ourselves above anything else. static const int LAYER_BASE = INT32_MAX - 10; static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s; +static constexpr float EPSILON = MotionEvent::ROUNDING_PRECISION; class SynchronousWindowInfosReportedListener : public gui::BnWindowInfosReportedListener { public: @@ -203,8 +204,8 @@ public: ASSERT_EQ(InputEventType::MOTION, ev->getType()); MotionEvent* mev = static_cast<MotionEvent*>(ev); EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction()); - EXPECT_EQ(x, mev->getX(0)); - EXPECT_EQ(y, mev->getY(0)); + EXPECT_NEAR(x, mev->getX(0), EPSILON); + EXPECT_NEAR(y, mev->getY(0), EPSILON); EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS); ev = consumeEvent(); @@ -1230,7 +1231,7 @@ public: consumer->setConsumerName(String8("Virtual disp consumer (MultiDisplayTests)")); consumer->setDefaultBufferSize(width, height); - class StubConsumerListener : public BnConsumerListener { + class StubConsumerListener : public IConsumerListener { virtual void onFrameAvailable(const BufferItem&) override {} virtual void onBuffersReleased() override {} virtual void onSidebandStreamChanged() override {} diff --git a/libs/gui/tests/Malicious.cpp b/libs/gui/tests/Malicious.cpp index 376420c42b..cc16383f39 100644 --- a/libs/gui/tests/Malicious.cpp +++ b/libs/gui/tests/Malicious.cpp @@ -129,7 +129,7 @@ private: int32_t mExpectedSlot = 0; }; -class FakeListener : public BnConsumerListener { +class FakeListener : public IConsumerListener { public: void onFrameAvailable(const BufferItem&) override {} void onBuffersReleased() override {} diff --git a/libs/gui/tests/MockConsumer.h b/libs/gui/tests/MockConsumer.h index 4a6c51c17d..2e8bc63fb7 100644 --- a/libs/gui/tests/MockConsumer.h +++ b/libs/gui/tests/MockConsumer.h @@ -18,7 +18,7 @@ namespace android { -struct MockConsumer : public BnConsumerListener { +struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} diff --git a/libs/gui/tests/MultiTextureConsumer_test.cpp b/libs/gui/tests/MultiTextureConsumer_test.cpp index 2428bb3110..7ae6f40f8c 100644 --- a/libs/gui/tests/MultiTextureConsumer_test.cpp +++ b/libs/gui/tests/MultiTextureConsumer_test.cpp @@ -34,8 +34,8 @@ protected: virtual void SetUp() { GLTest::SetUp(); - mGlConsumer = new GLConsumer(TEX_ID, GLConsumer::TEXTURE_EXTERNAL, true, false); - mSurface = mGlConsumer->getSurface(); + std::tie(mGlConsumer, mSurface) = + GLConsumer::create(TEX_ID, GLConsumer::TEXTURE_EXTERNAL, true, false); mANW = mSurface.get(); } diff --git a/libs/gui/tests/RegionSampling_test.cpp b/libs/gui/tests/RegionSampling_test.cpp index a0d8c53385..c35efe28a3 100644 --- a/libs/gui/tests/RegionSampling_test.cpp +++ b/libs/gui/tests/RegionSampling_test.cpp @@ -40,7 +40,7 @@ struct ChoreographerSync { std::unique_lock<decltype(mutex_)> lk(mutex_); auto check_event = [](auto const& ev) -> bool { - return ev.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC; + return ev.header.type == DisplayEventType::DISPLAY_EVENT_VSYNC; }; DisplayEventReceiver::Event ev_; int evs = receiver_.getEvents(&ev_, 1); diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp index 1c439cdb45..9570a369bd 100644 --- a/libs/gui/tests/StreamSplitter_test.cpp +++ b/libs/gui/tests/StreamSplitter_test.cpp @@ -32,7 +32,7 @@ namespace android { class StreamSplitterTest : public ::testing::Test {}; -struct FakeListener : public BnConsumerListener { +struct FakeListener : public IConsumerListener { virtual void onFrameAvailable(const BufferItem& /* item */) {} virtual void onBuffersReleased() {} virtual void onSidebandStreamChanged() {} diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index 59d05b673c..d3434ea288 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -40,8 +40,7 @@ protected: } virtual void SetUp() { - mST = new GLConsumer(123, GLConsumer::TEXTURE_EXTERNAL, true, false); - mSTC = mST->getSurface(); + std::tie(mST, mSTC) = GLConsumer::create(123, GLConsumer::TEXTURE_EXTERNAL, true, false); mANW = mSTC; // We need a valid GL context so we can test updateTexImage() @@ -727,8 +726,7 @@ protected: ASSERT_NE(EGL_NO_CONTEXT, mEglContext); for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { - sp<GLConsumer> st(new GLConsumer(i, GLConsumer::TEXTURE_EXTERNAL, true, false)); - sp<Surface> stc = st->getSurface(); + auto [st, stc] = GLConsumer::create(i, GLConsumer::TEXTURE_EXTERNAL, true, false); mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig, static_cast<ANativeWindow*>(stc.get()), nullptr); ASSERT_EQ(EGL_SUCCESS, eglGetError()); diff --git a/libs/gui/tests/SurfaceTextureGL.h b/libs/gui/tests/SurfaceTextureGL.h index 1309635afd..eb31cd1be7 100644 --- a/libs/gui/tests/SurfaceTextureGL.h +++ b/libs/gui/tests/SurfaceTextureGL.h @@ -38,8 +38,7 @@ protected: void SetUp() { GLTest::SetUp(); - mST = new GLConsumer(TEX_ID, GLConsumer::TEXTURE_EXTERNAL, true, false); - mSTC = mST->getSurface(); + std::tie(mST, mSTC) = GLConsumer::create(TEX_ID, GLConsumer::TEXTURE_EXTERNAL, true, false); mANW = mSTC; ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), TEST_PRODUCER_USAGE_BITS)); mTextureRenderer = new TextureRenderer(TEX_ID, mST); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 646e30e5a8..c4dcba856a 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -294,9 +294,7 @@ TEST_F(SurfaceTest, LayerCountIsOne) { TEST_F(SurfaceTest, QueryConsumerUsage) { const int TEST_USAGE_FLAGS = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER; - sp<BufferItemConsumer> c = new BufferItemConsumer(TEST_USAGE_FLAGS); - - sp<Surface> s = c->getSurface(); + auto [c, s] = BufferItemConsumer::create(TEST_USAGE_FLAGS); sp<ANativeWindow> anw(s); int flags = -1; @@ -309,10 +307,8 @@ TEST_F(SurfaceTest, QueryConsumerUsage) { TEST_F(SurfaceTest, QueryDefaultBuffersDataSpace) { const android_dataspace TEST_DATASPACE = HAL_DATASPACE_V0_SRGB; - sp<CpuConsumer> cpuConsumer = new CpuConsumer(1); + auto [cpuConsumer, s] = CpuConsumer::create(1); cpuConsumer->setDefaultBufferDataSpace(TEST_DATASPACE); - - sp<Surface> s = cpuConsumer->getSurface(); sp<ANativeWindow> anw(s); android_dataspace dataSpace; @@ -325,8 +321,7 @@ TEST_F(SurfaceTest, QueryDefaultBuffersDataSpace) { } TEST_F(SurfaceTest, SettingGenerationNumber) { - sp<CpuConsumer> cpuConsumer = new CpuConsumer(1); - sp<Surface> surface = cpuConsumer->getSurface(); + auto [cpuConsumer, surface] = CpuConsumer::create(1); sp<ANativeWindow> window(surface); // Allocate a buffer with a generation number of 0 @@ -603,7 +598,7 @@ TEST_F(SurfaceTest, TestGetLastDequeueStartTime) { ASSERT_GE(after, lastDequeueTime); } -class FakeConsumer : public BnConsumerListener { +class FakeConsumer : public IConsumerListener { public: void onFrameAvailable(const BufferItem& /*item*/) override {} void onBuffersReleased() override {} @@ -653,16 +648,7 @@ public: mSupportsPresent = supportsPresent; } - status_t setTransactionState( - const FrameTimelineInfo& /*frameTimelineInfo*/, Vector<ComposerState>& /*state*/, - Vector<DisplayState>& /*displays*/, uint32_t /*flags*/, - const sp<IBinder>& /*applyToken*/, InputWindowCommands /*inputWindowCommands*/, - int64_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, - const std::vector<client_cache_t>& /*cachedBuffer*/, bool /*hasListenerCallbacks*/, - const std::vector<ListenerCallbacks>& /*listenerCallbacks*/, uint64_t /*transactionId*/, - const std::vector<uint64_t>& /*mergedTransactionIds*/) override { - return NO_ERROR; - } + status_t setTransactionState(TransactionState&&) override { return NO_ERROR; } protected: IBinder* onAsBinder() override { return nullptr; } @@ -692,10 +678,11 @@ public: return binder::Status::ok(); } - binder::Status createVirtualDisplay(const std::string& /*displayName*/, bool /*isSecure*/, - const std::string& /*uniqueId*/, - float /*requestedRefreshRate*/, - sp<IBinder>* /*outDisplay*/) override { + binder::Status createVirtualDisplay( + const std::string& /*displayName*/, bool /*isSecure*/, + gui::ISurfaceComposer::OptimizationPolicy /*optimizationPolicy*/, + const std::string& /*uniqueId*/, float /*requestedRefreshRate*/, + sp<IBinder>* /*outDisplay*/) override { return binder::Status::ok(); } @@ -2180,8 +2167,7 @@ TEST_F(SurfaceTest, BatchOperations) { const int BUFFER_COUNT = 16; const int BATCH_SIZE = 8; - sp<CpuConsumer> cpuConsumer = new CpuConsumer(1); - sp<Surface> surface = cpuConsumer->getSurface(); + auto [cpuConsumer, surface] = CpuConsumer::create(1); sp<ANativeWindow> window(surface); sp<StubSurfaceListener> listener = new StubSurfaceListener(); @@ -2229,8 +2215,7 @@ TEST_F(SurfaceTest, BatchIllegalOperations) { const int BUFFER_COUNT = 16; const int BATCH_SIZE = 8; - sp<CpuConsumer> cpuConsumer = new CpuConsumer(1); - sp<Surface> surface = cpuConsumer->getSurface(); + auto [cpuConsumer, surface] = CpuConsumer::create(1); sp<ANativeWindow> window(surface); sp<StubSurfaceListener> listener = new StubSurfaceListener(); @@ -2252,6 +2237,52 @@ TEST_F(SurfaceTest, BatchIllegalOperations) { ASSERT_EQ(NO_ERROR, surface->disconnect(NATIVE_WINDOW_API_CPU)); } +TEST_F(SurfaceTest, setMaxDequeuedBufferCount_setMaxAcquiredBufferCount_allocations) { + // + // Set up the consumer and producer--nothing fancy. + // + auto [consumer, surface] = + BufferItemConsumer::create(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER); + sp<SurfaceListener> surfaceListener = sp<StubSurfaceListener>::make(); + surface->connect(NATIVE_WINDOW_API_CPU, surfaceListener); + sp<GraphicBuffer> buffer; + sp<Fence> fence; + + // + // These values are independent. The consumer can dequeue 3 and the consumer can acquire 3 at + // the same time. + // + ASSERT_EQ(OK, consumer->setMaxAcquiredBufferCount(3)); + ASSERT_EQ(OK, surface->setMaxDequeuedBufferCount(3)); + + // + // Take all three buffers out of the queue--a fourth can't be retrieved. Then queue them. + // + std::vector<Surface::BatchBuffer> dequeuedBuffers(3); + EXPECT_EQ(OK, surface->dequeueBuffers(&dequeuedBuffers)); + if (::com::android::graphics::libgui::flags::bq_always_use_max_dequeued_buffer_count()) { + EXPECT_EQ(INVALID_OPERATION, surface->dequeueBuffer(&buffer, &fence)); + } + + for (auto& batchBuffer : dequeuedBuffers) { + EXPECT_EQ(OK, + surface->queueBuffer(GraphicBuffer::from(batchBuffer.buffer), + sp<Fence>::make(batchBuffer.fenceFd))); + } + dequeuedBuffers.assign(3, {}); + + // + // Acquire all three, then we should be able to dequeue 3 more. + // + std::vector<BufferItem> acquiredBuffers(3); + for (auto& bufferItem : acquiredBuffers) { + EXPECT_EQ(OK, consumer->acquireBuffer(&bufferItem, 0)); + } + + EXPECT_EQ(OK, surface->dequeueBuffers(&dequeuedBuffers)); + EXPECT_EQ(INVALID_OPERATION, surface->dequeueBuffer(&buffer, &fence)); +} + #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) TEST_F(SurfaceTest, PlatformBufferMethods) { @@ -2377,8 +2408,7 @@ TEST_F(SurfaceTest, QueueAcquireReleaseDequeue_CalledInStack_DoesNotDeadlock) { sp<IGraphicBufferConsumer> bqConsumer; BufferQueue::createBufferQueue(&bqProducer, &bqConsumer); - sp<BufferItemConsumer> consumer = sp<BufferItemConsumer>::make(bqConsumer, 3); - sp<Surface> surface = sp<Surface>::make(bqProducer); + auto [consumer, surface] = BufferItemConsumer::create(3); sp<ImmediateReleaseConsumerListener> consumerListener = sp<ImmediateReleaseConsumerListener>::make(consumer); consumer->setFrameAvailableListener(consumerListener); diff --git a/libs/gui/tests/TransactionState_test.cpp b/libs/gui/tests/TransactionState_test.cpp new file mode 100644 index 0000000000..179b264dbf --- /dev/null +++ b/libs/gui/tests/TransactionState_test.cpp @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gmock/gmock.h> + +#include <gtest/gtest.h> +#include <unordered_map> +#include "android/gui/FocusRequest.h" +#include "binder/Binder.h" +#include "binder/Parcel.h" +#include "gtest/gtest.h" +#include "gui/LayerState.h" +#include "gui/WindowInfo.h" + +#include "gui/TransactionState.h" + +namespace android { + +void sprintf(std::string& out, const char* format, ...) { + va_list arg_list; + va_start(arg_list, format); + + int len = vsnprintf(nullptr, 0, format, arg_list); + if (len < 0) { + va_end(arg_list); + } + std::string line(len, '\0'); + int written = vsnprintf(line.data(), len + 1, format, arg_list); + if (written != len) { + va_end(arg_list); + } + line.pop_back(); + out += line; + va_end(arg_list); +} + +constexpr std::string dump_struct(auto& x) { + std::string s; +#if __has_builtin(__builtin_dump_struct) + __builtin_dump_struct(&x, sprintf, s); +#else + (void)x; +#endif + return s; +} + +void PrintTo(const TransactionState& state, ::std::ostream* os) { + *os << dump_struct(state); + *os << state.mFrameTimelineInfo.toString(); + for (auto mergedId : state.mMergedTransactionIds) { + *os << mergedId << ","; + } +} + +void PrintTo(const ComposerState& state, ::std::ostream* os) { + *os << dump_struct(state.state); + *os << state.state.getWindowInfo(); +} + +// In case EXPECT_EQ fails, this function is useful to pinpoint exactly which +// field did not compare ==. +void Compare(const TransactionState& s1, const TransactionState& s2) { + EXPECT_EQ(s1.mId, s2.mId); + EXPECT_EQ(s1.mMergedTransactionIds, s2.mMergedTransactionIds); + EXPECT_EQ(s1.mFlags, s2.mFlags); + EXPECT_EQ(s1.mFrameTimelineInfo, s2.mFrameTimelineInfo); + EXPECT_EQ(s1.mDesiredPresentTime, s2.mDesiredPresentTime); + EXPECT_EQ(s1.mIsAutoTimestamp, s2.mIsAutoTimestamp); + EXPECT_EQ(s1.mApplyToken, s2.mApplyToken); + EXPECT_EQ(s1.mMayContainBuffer, s2.mMayContainBuffer); + EXPECT_EQ(s1.mLogCallPoints, s2.mLogCallPoints); + EXPECT_EQ(s1.mDisplayStates.size(), s2.mDisplayStates.size()); + EXPECT_THAT(s1.mDisplayStates, ::testing::ContainerEq(s2.mDisplayStates)); + EXPECT_EQ(s1.mComposerStates.size(), s2.mComposerStates.size()); + EXPECT_EQ(s1.mComposerStates, s2.mComposerStates); + EXPECT_EQ(s1.mInputWindowCommands, s2.mInputWindowCommands); + EXPECT_EQ(s1.mUncacheBuffers, s2.mUncacheBuffers); + EXPECT_EQ(s1.mHasListenerCallbacks, s2.mHasListenerCallbacks); + EXPECT_EQ(s1.mListenerCallbacks.size(), s2.mListenerCallbacks.size()); + EXPECT_EQ(s1.mListenerCallbacks, s2.mListenerCallbacks); +} + +std::unique_ptr<std::unordered_map<int, sp<BBinder>>> createTokenMap(size_t maxSize) { + auto result = std::make_unique<std::unordered_map<int, sp<BBinder>>>(); + for (size_t i = 0; i < maxSize; ++i) { + result->emplace(i, sp<BBinder>::make()); + } + return result; +} + +constexpr size_t kMaxComposerStates = 2; +ComposerState createComposerStateForTest(size_t i) { + static const auto* const sLayerHandle = createTokenMap(kMaxComposerStates).release(); + + ComposerState state; + state.state.what = layer_state_t::eFlagsChanged; + state.state.surface = sLayerHandle->at(i); + state.state.layerId = i; + state.state.flags = 20 * i; + return state; +} + +constexpr size_t kMaxDisplayStates = 5; +DisplayState createDisplayStateForTest(size_t i) { + static const auto* const sDisplayTokens = createTokenMap(kMaxDisplayStates).release(); + + DisplayState displayState; + displayState.what = DisplayState::eFlagsChanged; + displayState.token = sDisplayTokens->at(i); + displayState.flags = 20 * i; + return displayState; +} + +TransactionState createTransactionStateForTest() { + static sp<BBinder> sApplyToken = sp<BBinder>::make(); + + TransactionState state; + state.mId = 123; + state.mMergedTransactionIds.push_back(15); + state.mMergedTransactionIds.push_back(0); + state.mFrameTimelineInfo.vsyncId = 14; + state.mDesiredPresentTime = 11; + state.mIsAutoTimestamp = true; + state.mApplyToken = sApplyToken; + for (size_t i = 0; i < kMaxDisplayStates; i++) { + state.mDisplayStates.push_back(createDisplayStateForTest(i)); + } + for (size_t i = 0; i < kMaxComposerStates; i++) { + state.mComposerStates.push_back(createComposerStateForTest(i)); + } + static const auto* const sFocusRequestTokens = createTokenMap(5).release(); + for (int i = 0; i < 5; i++) { + gui::FocusRequest request; + request.token = sFocusRequestTokens->at(i); + request.timestamp = i; + state.mInputWindowCommands.addFocusRequest(request); + } + static const auto* const sCacheToken = createTokenMap(5).release(); + for (int i = 0; i < 5; i++) { + client_cache_t cache; + cache.token = sCacheToken->at(i); + cache.id = i; + state.mUncacheBuffers.emplace_back(std::move(cache)); + } + static const auto* const sListenerCallbacks = []() { + auto* callbacks = new std::vector<ListenerCallbacks>(); + for (int i = 0; i < 5; i++) { + callbacks->emplace_back(sp<BBinder>::make(), + std::unordered_set<CallbackId, CallbackIdHash>{}); + } + return callbacks; + }(); + state.mHasListenerCallbacks = true; + state.mListenerCallbacks = *sListenerCallbacks; + return state; +} + +TransactionState createEmptyTransaction(uint64_t id) { + TransactionState state; + state.mId = id; + return state; +} + +TEST(TransactionStateTest, parcel) { + TransactionState state = createTransactionStateForTest(); + Parcel p; + state.writeToParcel(&p); + p.setDataPosition(0); + TransactionState parcelledState; + parcelledState.readFromParcel(&p); + EXPECT_EQ(state, parcelledState); +}; + +TEST(TransactionStateTest, parcelDisplayState) { + DisplayState state = createDisplayStateForTest(0); + Parcel p; + state.write(p); + p.setDataPosition(0); + DisplayState parcelledState; + parcelledState.read(p); + EXPECT_EQ(state, parcelledState); +}; + +TEST(TransactionStateTest, parcelLayerState) { + ComposerState state = createComposerStateForTest(0); + Parcel p; + state.write(p); + p.setDataPosition(0); + ComposerState parcelledState; + parcelledState.read(p); + EXPECT_EQ(state, parcelledState); +}; + +TEST(TransactionStateTest, parcelEmptyState) { + TransactionState state; + Parcel p; + state.writeToParcel(&p); + p.setDataPosition(0); + TransactionState parcelledState; + state.readFromParcel(&p); + EXPECT_EQ(state, parcelledState); +}; + +TEST(TransactionStateTest, mergeLayerState) { + ComposerState composerState = createComposerStateForTest(0); + ComposerState update; + update.state.surface = composerState.state.surface; + update.state.layerId = 0; + update.state.what = layer_state_t::eAlphaChanged; + update.state.color.a = .42; + composerState.state.merge(update.state); + + ComposerState expectedMergedState = createComposerStateForTest(0); + expectedMergedState.state.what |= layer_state_t::eAlphaChanged; + expectedMergedState.state.color.a = .42; + EXPECT_EQ(composerState, expectedMergedState); +}; + +TEST(TransactionStateTest, merge) { + // Setup. + static constexpr uint64_t kUpdateTransactionId = 200; + + TransactionState state = createTransactionStateForTest(); + + TransactionState update; + update.mId = kUpdateTransactionId; + { + ComposerState composerState; + composerState.state.surface = state.mComposerStates[0].state.surface; + composerState.state.what = layer_state_t::eAlphaChanged; + composerState.state.color.a = .42; + update.mComposerStates.push_back(composerState); + } + { + ComposerState composerState; + composerState.state.surface = state.mComposerStates[1].state.surface; + composerState.state.what = layer_state_t::eBufferChanged; + update.mComposerStates.push_back(composerState); + } + int32_t overrwiteLayerId = -1; + // Mutation. + state.merge(std::move(update), + [&overrwiteLayerId](layer_state_t ls) { overrwiteLayerId = ls.layerId; }); + // Assertions. + EXPECT_EQ(1, overrwiteLayerId); + EXPECT_EQ(update, createEmptyTransaction(update.getId())); + + TransactionState expectedMergedState = createTransactionStateForTest(); + expectedMergedState.mMergedTransactionIds + .insert(expectedMergedState.mMergedTransactionIds.begin(), kUpdateTransactionId); + expectedMergedState.mComposerStates.at(0).state.what |= layer_state_t::eAlphaChanged; + expectedMergedState.mComposerStates.at(0).state.color.a = .42; + expectedMergedState.mComposerStates.at(1).state.what |= layer_state_t::eBufferChanged; + auto inputCommands = expectedMergedState.mInputWindowCommands; + + // desired present time is not merged. + expectedMergedState.mDesiredPresentTime = state.mDesiredPresentTime; + + EXPECT_EQ(state.mComposerStates[0], expectedMergedState.mComposerStates[0]); + EXPECT_EQ(state.mInputWindowCommands, expectedMergedState.mInputWindowCommands); + EXPECT_EQ(state, expectedMergedState); +}; + +TEST(TransactionStateTest, clear) { + TransactionState state = createTransactionStateForTest(); + state.clear(); + TransactionState emptyState = createEmptyTransaction(state.getId()); + EXPECT_EQ(state, emptyState); +}; + +} // namespace android diff --git a/libs/gui/tests/WindowInfo_test.cpp b/libs/gui/tests/WindowInfo_test.cpp index ce22082a9f..e3f9a07b34 100644 --- a/libs/gui/tests/WindowInfo_test.cpp +++ b/libs/gui/tests/WindowInfo_test.cpp @@ -40,7 +40,18 @@ TEST(WindowInfo, ParcellingWithoutToken) { ASSERT_EQ(OK, i.writeToParcel(&p)); p.setDataPosition(0); i2.readFromParcel(&p); - ASSERT_TRUE(i2.token == nullptr); + ASSERT_EQ(i2.token, nullptr); +} + +TEST(WindowInfo, ParcellingWithoutCloneTransform) { + WindowInfo i, i2; + i.cloneLayerStackTransform.reset(); + + Parcel p; + ASSERT_EQ(OK, i.writeToParcel(&p)); + p.setDataPosition(0); + i2.readFromParcel(&p); + ASSERT_EQ(i2.cloneLayerStackTransform, std::nullopt); } TEST(WindowInfo, Parcelling) { @@ -71,6 +82,8 @@ TEST(WindowInfo, Parcelling) { i.applicationInfo.token = new BBinder(); i.applicationInfo.dispatchingTimeoutMillis = 0x12345678ABCD; i.focusTransferTarget = new BBinder(); + i.cloneLayerStackTransform = ui::Transform(); + i.cloneLayerStackTransform->set({5, -1, 100, 4, 0, 40, 0, 0, 1}); Parcel p; i.writeToParcel(&p); @@ -100,6 +113,7 @@ TEST(WindowInfo, Parcelling) { ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle); ASSERT_EQ(i.applicationInfo, i2.applicationInfo); ASSERT_EQ(i.focusTransferTarget, i2.focusTransferTarget); + ASSERT_EQ(i.cloneLayerStackTransform, i2.cloneLayerStackTransform); } TEST(InputApplicationInfo, Parcelling) { diff --git a/libs/gui/tests/testserver/TestServer.cpp b/libs/gui/tests/testserver/TestServer.cpp index cd8824e355..17d1b4abe9 100644 --- a/libs/gui/tests/testserver/TestServer.cpp +++ b/libs/gui/tests/testserver/TestServer.cpp @@ -45,7 +45,7 @@ namespace android { namespace { -class TestConsumerListener : public BnConsumerListener { +class TestConsumerListener : public IConsumerListener { virtual void onFrameAvailable(const BufferItem&) override {} virtual void onBuffersReleased() override {} virtual void onSidebandStreamChanged() override {} diff --git a/libs/input/AccelerationCurve.cpp b/libs/input/AccelerationCurve.cpp index 0b47f3e6e7..1ed9794105 100644 --- a/libs/input/AccelerationCurve.cpp +++ b/libs/input/AccelerationCurve.cpp @@ -47,9 +47,9 @@ constexpr std::array<double, 15> kSensitivityFactors = {1, 2, 4, 6, 7, 8, // in faster pointer movements. // // The base gain is calculated using a linear mapping function that maps the -// sensitivity range [-7, 7] to a base gain range [0.5, 2.0]. +// sensitivity range [-7, 7] to a base gain range [1.0, 3.5]. double calculateBaseGain(int32_t sensitivity) { - return 0.5 + (sensitivity + 7) * (2.0 - 0.5) / (7 + 7); + return 1.0 + (sensitivity + 7) * (3.5 - 1.0) / (7 + 7); } } // namespace diff --git a/libs/input/Android.bp b/libs/input/Android.bp index 389fb7f6ab..52e0276cad 100644 --- a/libs/input/Android.bp +++ b/libs/input/Android.bp @@ -27,9 +27,9 @@ filegroup { name: "inputconstants_aidl", srcs: [ "android/os/IInputConstants.aidl", + "android/os/InputConfig.aidl", "android/os/InputEventInjectionResult.aidl", "android/os/InputEventInjectionSync.aidl", - "android/os/InputConfig.aidl", "android/os/MotionEventFlag.aidl", "android/os/PointerIconType.aidl", ], @@ -85,56 +85,63 @@ rust_bindgen { source_stem: "bindings", bindgen_flags: [ - "--verbose", - "--allowlist-var=AMOTION_EVENT_ACTION_CANCEL", - "--allowlist-var=AMOTION_EVENT_ACTION_UP", - "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_DOWN", - "--allowlist-var=AMOTION_EVENT_ACTION_DOWN", - "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT", - "--allowlist-var=MAX_POINTER_ID", - "--allowlist-var=AINPUT_SOURCE_CLASS_NONE", + "--allowlist-var=AINPUT_KEYBOARD_TYPE_ALPHABETIC", + "--allowlist-var=AINPUT_KEYBOARD_TYPE_NONE", + "--allowlist-var=AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC", + "--allowlist-var=AINPUT_SOURCE_BLUETOOTH_STYLUS", "--allowlist-var=AINPUT_SOURCE_CLASS_BUTTON", - "--allowlist-var=AINPUT_SOURCE_CLASS_POINTER", + "--allowlist-var=AINPUT_SOURCE_CLASS_JOYSTICK", "--allowlist-var=AINPUT_SOURCE_CLASS_NAVIGATION", + "--allowlist-var=AINPUT_SOURCE_CLASS_NONE", + "--allowlist-var=AINPUT_SOURCE_CLASS_POINTER", "--allowlist-var=AINPUT_SOURCE_CLASS_POSITION", - "--allowlist-var=AINPUT_SOURCE_CLASS_JOYSTICK", - "--allowlist-var=AINPUT_SOURCE_UNKNOWN", - "--allowlist-var=AINPUT_SOURCE_KEYBOARD", "--allowlist-var=AINPUT_SOURCE_DPAD", "--allowlist-var=AINPUT_SOURCE_GAMEPAD", - "--allowlist-var=AINPUT_SOURCE_TOUCHSCREEN", + "--allowlist-var=AINPUT_SOURCE_HDMI", + "--allowlist-var=AINPUT_SOURCE_JOYSTICK", + "--allowlist-var=AINPUT_SOURCE_KEYBOARD", "--allowlist-var=AINPUT_SOURCE_MOUSE", - "--allowlist-var=AINPUT_SOURCE_STYLUS", - "--allowlist-var=AINPUT_SOURCE_BLUETOOTH_STYLUS", - "--allowlist-var=AINPUT_SOURCE_TRACKBALL", "--allowlist-var=AINPUT_SOURCE_MOUSE_RELATIVE", + "--allowlist-var=AINPUT_SOURCE_ROTARY_ENCODER", + "--allowlist-var=AINPUT_SOURCE_SENSOR", + "--allowlist-var=AINPUT_SOURCE_STYLUS", "--allowlist-var=AINPUT_SOURCE_TOUCHPAD", + "--allowlist-var=AINPUT_SOURCE_TOUCHSCREEN", "--allowlist-var=AINPUT_SOURCE_TOUCH_NAVIGATION", - "--allowlist-var=AINPUT_SOURCE_JOYSTICK", - "--allowlist-var=AINPUT_SOURCE_HDMI", - "--allowlist-var=AINPUT_SOURCE_SENSOR", - "--allowlist-var=AINPUT_SOURCE_ROTARY_ENCODER", - "--allowlist-var=AINPUT_KEYBOARD_TYPE_NONE", - "--allowlist-var=AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC", - "--allowlist-var=AINPUT_KEYBOARD_TYPE_ALPHABETIC", - "--allowlist-var=AMETA_NONE", - "--allowlist-var=AMETA_ALT_ON", + "--allowlist-var=AINPUT_SOURCE_TRACKBALL", + "--allowlist-var=AINPUT_SOURCE_UNKNOWN", "--allowlist-var=AMETA_ALT_LEFT_ON", + "--allowlist-var=AMETA_ALT_ON", "--allowlist-var=AMETA_ALT_RIGHT_ON", - "--allowlist-var=AMETA_SHIFT_ON", - "--allowlist-var=AMETA_SHIFT_LEFT_ON", - "--allowlist-var=AMETA_SHIFT_RIGHT_ON", - "--allowlist-var=AMETA_SYM_ON", - "--allowlist-var=AMETA_FUNCTION_ON", - "--allowlist-var=AMETA_CTRL_ON", + "--allowlist-var=AMETA_CAPS_LOCK_ON", "--allowlist-var=AMETA_CTRL_LEFT_ON", + "--allowlist-var=AMETA_CTRL_ON", "--allowlist-var=AMETA_CTRL_RIGHT_ON", - "--allowlist-var=AMETA_META_ON", + "--allowlist-var=AMETA_FUNCTION_ON", "--allowlist-var=AMETA_META_LEFT_ON", + "--allowlist-var=AMETA_META_ON", "--allowlist-var=AMETA_META_RIGHT_ON", - "--allowlist-var=AMETA_CAPS_LOCK_ON", + "--allowlist-var=AMETA_NONE", "--allowlist-var=AMETA_NUM_LOCK_ON", "--allowlist-var=AMETA_SCROLL_LOCK_ON", + "--allowlist-var=AMETA_SHIFT_LEFT_ON", + "--allowlist-var=AMETA_SHIFT_ON", + "--allowlist-var=AMETA_SHIFT_RIGHT_ON", + "--allowlist-var=AMETA_SYM_ON", + "--allowlist-var=AMOTION_EVENT_ACTION_CANCEL", + "--allowlist-var=AMOTION_EVENT_ACTION_DOWN", + "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_DOWN", + "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT", + "--allowlist-var=AMOTION_EVENT_ACTION_UP", + "--allowlist-var=AMOTION_EVENT_BUTTON_BACK", + "--allowlist-var=AMOTION_EVENT_BUTTON_FORWARD", + "--allowlist-var=AMOTION_EVENT_BUTTON_PRIMARY", + "--allowlist-var=AMOTION_EVENT_BUTTON_SECONDARY", + "--allowlist-var=AMOTION_EVENT_BUTTON_STYLUS_PRIMARY", + "--allowlist-var=AMOTION_EVENT_BUTTON_STYLUS_SECONDARY", + "--allowlist-var=AMOTION_EVENT_BUTTON_TERTIARY", + "--allowlist-var=MAX_POINTER_ID", + "--verbose", ], static_libs: [ @@ -143,9 +150,9 @@ rust_bindgen { ], shared_libs: ["libc++"], header_libs: [ - "native_headers", - "jni_headers", "flatbuffer_headers", + "jni_headers", + "native_headers", ], } @@ -179,8 +186,8 @@ cc_library_static { host_supported: true, cflags: [ "-Wall", - "-Wextra", "-Werror", + "-Wextra", ], srcs: [ "FromRustToCpp.cpp", @@ -205,30 +212,32 @@ cc_library { cpp_std: "c++20", host_supported: true, cflags: [ + "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION", "-Wall", - "-Wextra", "-Werror", + "-Wextra", "-Wno-unused-parameter", - "-Wthread-safety", "-Wshadow", "-Wshadow-field-in-constructor-modified", "-Wshadow-uncaptured-local", - "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION", + "-Wthread-safety", ], srcs: [ "AccelerationCurve.cpp", "CoordinateFilter.cpp", + "DisplayTopologyGraph.cpp", "Input.cpp", "InputConsumer.cpp", "InputConsumerNoResampling.cpp", "InputDevice.cpp", "InputEventLabels.cpp", + "InputFlags.cpp", "InputTransport.cpp", "InputVerifier.cpp", - "Keyboard.cpp", "KeyCharacterMap.cpp", - "KeyboardClassifier.cpp", "KeyLayoutMap.cpp", + "Keyboard.cpp", + "KeyboardClassifier.cpp", "MotionPredictor.cpp", "MotionPredictorMetricsManager.cpp", "OneEuroFilter.cpp", @@ -262,13 +271,14 @@ cc_library { shared_libs: [ "android.companion.virtualdevice.flags-aconfig-cc", + "com.android.window.flags.window-aconfig_flags_c_lib", + "libPlatformProperties", "libaconfig_storage_read_api_cc", "libbase", "libbinder", "libbinder_ndk", "libcutils", "liblog", - "libPlatformProperties", "libtinyxml2", "libutils", "libz", // needed by libkernelconfigs @@ -287,15 +297,15 @@ cc_library { static_libs: [ "inputconstants-cpp", - "libui-types", - "libtflite_static", "libkernelconfigs", + "libtflite_static", + "libui-types", ], whole_static_libs: [ "com.android.input.flags-aconfig-cc", - "libinput_rust_ffi", "iinputflinger_aidl_lib_static", + "libinput_rust_ffi", ], export_static_lib_headers: [ @@ -310,8 +320,8 @@ cc_library { target: { android: { required: [ - "motion_predictor_model_prebuilt", "motion_predictor_model_config", + "motion_predictor_model_prebuilt", ], static_libs: [ "libstatslog_libinput", @@ -372,9 +382,9 @@ cc_defaults { cpp_std: "c++20", host_supported: true, shared_libs: [ - "libutils", "libbase", "liblog", + "libutils", ], } diff --git a/libs/input/DisplayTopologyGraph.cpp b/libs/input/DisplayTopologyGraph.cpp new file mode 100644 index 0000000000..934f2e8135 --- /dev/null +++ b/libs/input/DisplayTopologyGraph.cpp @@ -0,0 +1,144 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "DisplayTopologyValidator" + +#include <android-base/logging.h> +#include <android-base/stringprintf.h> +#include <ftl/enum.h> +#include <input/DisplayTopologyGraph.h> +#include <input/PrintTools.h> +#include <ui/LogicalDisplayId.h> + +#include <algorithm> + +#define INDENT " " + +namespace android { + +namespace { + +DisplayTopologyPosition getOppositePosition(DisplayTopologyPosition position) { + switch (position) { + case DisplayTopologyPosition::LEFT: + return DisplayTopologyPosition::RIGHT; + case DisplayTopologyPosition::TOP: + return DisplayTopologyPosition::BOTTOM; + case DisplayTopologyPosition::RIGHT: + return DisplayTopologyPosition::LEFT; + case DisplayTopologyPosition::BOTTOM: + return DisplayTopologyPosition::TOP; + } +} + +bool validatePrimaryDisplay(const android::DisplayTopologyGraph& displayTopologyGraph) { + return displayTopologyGraph.primaryDisplayId != ui::LogicalDisplayId::INVALID && + displayTopologyGraph.graph.contains(displayTopologyGraph.primaryDisplayId); +} + +bool validateTopologyGraph(const android::DisplayTopologyGraph& displayTopologyGraph) { + for (const auto& [sourceDisplay, adjacentDisplays] : displayTopologyGraph.graph) { + for (const DisplayTopologyAdjacentDisplay& adjacentDisplay : adjacentDisplays) { + const auto adjacentGraphIt = displayTopologyGraph.graph.find(adjacentDisplay.displayId); + if (adjacentGraphIt == displayTopologyGraph.graph.end()) { + LOG(ERROR) << "Missing adjacent display in topology graph: " + << adjacentDisplay.displayId << " for source " << sourceDisplay; + return false; + } + const auto reverseEdgeIt = + std::find_if(adjacentGraphIt->second.begin(), adjacentGraphIt->second.end(), + [sourceDisplay](const DisplayTopologyAdjacentDisplay& + reverseAdjacentDisplay) { + return sourceDisplay == reverseAdjacentDisplay.displayId; + }); + if (reverseEdgeIt == adjacentGraphIt->second.end()) { + LOG(ERROR) << "Missing reverse edge in topology graph for: " << sourceDisplay + << " -> " << adjacentDisplay.displayId; + return false; + } + DisplayTopologyPosition expectedPosition = + getOppositePosition(adjacentDisplay.position); + if (reverseEdgeIt->position != expectedPosition) { + LOG(ERROR) << "Unexpected reverse edge for: " << sourceDisplay << " -> " + << adjacentDisplay.displayId + << " expected position: " << ftl::enum_string(expectedPosition) + << " actual " << ftl::enum_string(reverseEdgeIt->position); + return false; + } + if (reverseEdgeIt->offsetDp != -adjacentDisplay.offsetDp) { + LOG(ERROR) << "Unexpected reverse edge offset: " << sourceDisplay << " -> " + << adjacentDisplay.displayId + << " expected offset: " << -adjacentDisplay.offsetDp << " actual " + << reverseEdgeIt->offsetDp; + return false; + } + } + } + return true; +} + +bool validateDensities(const android::DisplayTopologyGraph& displayTopologyGraph) { + for (const auto& [sourceDisplay, adjacentDisplays] : displayTopologyGraph.graph) { + if (!displayTopologyGraph.displaysDensity.contains(sourceDisplay)) { + LOG(ERROR) << "Missing density value in topology graph for display: " << sourceDisplay; + return false; + } + } + return true; +} + +std::string logicalDisplayIdToString(const ui::LogicalDisplayId& displayId) { + return base::StringPrintf("displayId(%d)", displayId.val()); +} + +std::string adjacentDisplayToString(const DisplayTopologyAdjacentDisplay& adjacentDisplay) { + return adjacentDisplay.dump(); +} + +std::string adjacentDisplayVectorToString( + const std::vector<DisplayTopologyAdjacentDisplay>& adjacentDisplays) { + return dumpVector(adjacentDisplays, adjacentDisplayToString); +} + +} // namespace + +std::string DisplayTopologyAdjacentDisplay::dump() const { + std::string dump; + dump += base::StringPrintf("DisplayTopologyAdjacentDisplay: {displayId: %d, position: %s, " + "offsetDp: %f}", + displayId.val(), ftl::enum_string(position).c_str(), offsetDp); + return dump; +} + +bool DisplayTopologyGraph::isValid() const { + return validatePrimaryDisplay(*this) && validateTopologyGraph(*this) && + validateDensities(*this); +} + +std::string DisplayTopologyGraph::dump() const { + std::string dump; + dump += base::StringPrintf("PrimaryDisplayId: %d\n", primaryDisplayId.val()); + dump += base::StringPrintf("TopologyGraph:\n"); + dump += addLinePrefix(dumpMap(graph, logicalDisplayIdToString, adjacentDisplayVectorToString), + INDENT); + dump += "\n"; + dump += base::StringPrintf("DisplaysDensity:\n"); + dump += addLinePrefix(dumpMap(displaysDensity, logicalDisplayIdToString), INDENT); + dump += "\n"; + return dump; +} + +} // namespace android diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 65a088eb6d..155ea000e3 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -284,6 +284,36 @@ bool isStylusEvent(uint32_t source, const std::vector<PointerProperties>& proper return false; } +bool isStylusHoverEvent(uint32_t source, const std::vector<PointerProperties>& properties, + int32_t action) { + return isStylusEvent(source, properties) && isHoverAction(action); +} + +bool isFromMouse(uint32_t source, ToolType toolType) { + return isFromSource(source, AINPUT_SOURCE_MOUSE) && toolType == ToolType::MOUSE; +} + +bool isFromTouchpad(uint32_t source, ToolType toolType) { + return isFromSource(source, AINPUT_SOURCE_MOUSE) && toolType == ToolType::FINGER; +} + +bool isFromDrawingTablet(uint32_t source, ToolType toolType) { + return isFromSource(source, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS) && + isStylusToolType(toolType); +} + +bool isHoverAction(int32_t action) { + return action == AMOTION_EVENT_ACTION_HOVER_ENTER || + action == AMOTION_EVENT_ACTION_HOVER_MOVE || action == AMOTION_EVENT_ACTION_HOVER_EXIT; +} + +bool isMouseOrTouchpad(uint32_t sources) { + // Check if this is a mouse or touchpad, but not a drawing tablet. + return isFromSource(sources, AINPUT_SOURCE_MOUSE_RELATIVE) || + (isFromSource(sources, AINPUT_SOURCE_MOUSE) && + !isFromSource(sources, AINPUT_SOURCE_STYLUS)); +} + VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event) { return {{VerifiedInputEvent::Type::KEY, event.getDeviceId(), event.getEventTime(), event.getSource(), event.getDisplayId()}, diff --git a/libs/input/InputConsumerNoResampling.cpp b/libs/input/InputConsumerNoResampling.cpp index cd8582182a..6087461f6c 100644 --- a/libs/input/InputConsumerNoResampling.cpp +++ b/libs/input/InputConsumerNoResampling.cpp @@ -18,6 +18,7 @@ #define ATRACE_TAG ATRACE_TAG_INPUT #include <inttypes.h> +#include <set> #include <android-base/logging.h> #include <android-base/properties.h> diff --git a/libs/input/InputFlags.cpp b/libs/input/InputFlags.cpp new file mode 100644 index 0000000000..6aa9ae6b16 --- /dev/null +++ b/libs/input/InputFlags.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <input/InputFlags.h> + +#include <android-base/logging.h> +#include <com_android_input_flags.h> +#include <com_android_window_flags.h> +#include <cutils/properties.h> + +#include <string> + +namespace android { + +bool InputFlags::connectedDisplaysCursorEnabled() { + if (!com::android::window::flags::enable_desktop_mode_through_dev_option()) { + return com::android::input::flags::connected_displays_cursor(); + } + static std::optional<bool> cachedDevOption; + if (!cachedDevOption.has_value()) { + char value[PROPERTY_VALUE_MAX]; + constexpr static auto sysprop_name = "persist.wm.debug.desktop_experience_devopts"; + const int devOptionEnabled = + property_get(sysprop_name, value, nullptr) > 0 ? std::atoi(value) : 0; + cachedDevOption = devOptionEnabled == 1; + } + if (cachedDevOption.value_or(false)) { + return true; + } + return com::android::input::flags::connected_displays_cursor(); +} + +bool InputFlags::connectedDisplaysCursorAndAssociatedDisplayCursorBugfixEnabled() { + return connectedDisplaysCursorEnabled() && + com::android::input::flags::connected_displays_associated_display_cursor_bugfix(); +} + +} // namespace android
\ No newline at end of file diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 56ccaab9ad..d388d48e8d 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -651,9 +651,9 @@ status_t InputPublisher::publishMotionEvent( const status_t status = mChannel->sendMessage(&msg); if (status == OK && verifyEvents()) { - Result<void> result = - mInputVerifier.processMovement(deviceId, source, action, pointerCount, - pointerProperties, pointerCoords, flags); + Result<void> result = mInputVerifier.processMovement(deviceId, source, action, actionButton, + pointerCount, pointerProperties, + pointerCoords, flags, buttonState); if (!result.ok()) { LOG(ERROR) << "Bad stream: " << result.error(); return BAD_VALUE; diff --git a/libs/input/InputVerifier.cpp b/libs/input/InputVerifier.cpp index cec244539e..7811acefd0 100644 --- a/libs/input/InputVerifier.cpp +++ b/libs/input/InputVerifier.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "InputVerifier" #include <android-base/logging.h> +#include <com_android_input_flags.h> #include <input/InputVerifier.h> #include "input_cxx_bridge.rs.h" @@ -26,17 +27,23 @@ using android::input::RustPointerProperties; using DeviceId = int32_t; +namespace input_flags = com::android::input::flags; + namespace android { // --- InputVerifier --- InputVerifier::InputVerifier(const std::string& name) - : mVerifier(android::input::verifier::create(rust::String::lossy(name))){}; + : mVerifier( + android::input::verifier::create(rust::String::lossy(name), + input_flags::enable_button_state_verification())) { +} Result<void> InputVerifier::processMovement(DeviceId deviceId, int32_t source, int32_t action, - uint32_t pointerCount, + int32_t actionButton, uint32_t pointerCount, const PointerProperties* pointerProperties, - const PointerCoords* pointerCoords, int32_t flags) { + const PointerCoords* pointerCoords, int32_t flags, + int32_t buttonState) { std::vector<RustPointerProperties> rpp; for (size_t i = 0; i < pointerCount; i++) { rpp.emplace_back(RustPointerProperties{.id = pointerProperties[i].id}); @@ -44,7 +51,9 @@ Result<void> InputVerifier::processMovement(DeviceId deviceId, int32_t source, i rust::Slice<const RustPointerProperties> properties{rpp.data(), rpp.size()}; rust::String errorMessage = android::input::verifier::process_movement(*mVerifier, deviceId, source, action, - properties, static_cast<uint32_t>(flags)); + actionButton, properties, + static_cast<uint32_t>(flags), + static_cast<uint32_t>(buttonState)); if (errorMessage.empty()) { return {}; } else { diff --git a/libs/input/android/os/IInputConstants.aidl b/libs/input/android/os/IInputConstants.aidl index 6ce3fba477..4b87dab01b 100644 --- a/libs/input/android/os/IInputConstants.aidl +++ b/libs/input/android/os/IInputConstants.aidl @@ -43,8 +43,9 @@ interface IInputConstants const int INVALID_INPUT_DEVICE_ID = -2; /** - * The input event was injected from accessibility. Used in policyFlags for input event - * injection. + * The input event was injected from some AccessibilityService, which may be either an + * Accessibility Tool OR a service using that API for purposes other than assisting users with + * disabilities. Used in policyFlags for input event injection. */ const int POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY = 0x20000; @@ -55,18 +56,33 @@ interface IInputConstants const int POLICY_FLAG_KEY_GESTURE_TRIGGERED = 0x40000; /** + * The input event was injected from an AccessibilityService with the + * AccessibilityServiceInfo#isAccessibilityTool property set to true. These services (known as + * "Accessibility Tools") are used to assist users with disabilities, so events from these + * services should be able to reach all Views including Views which set + * View#isAccessibilityDataSensitive to true. Used in policyFlags for input event injection. + */ + const int POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL = 0x80000; + + /** * Common input event flag used for both motion and key events for a gesture or pointer being * canceled. */ const int INPUT_EVENT_FLAG_CANCELED = 0x20; /** - * Common input event flag used for both motion and key events, indicating that the event - * was generated or modified by accessibility service. + * Input event flag used for both motion and key events. + * See POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY for more information. */ const int INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT = 0x800; /** + * Input event flag used for motion events. + * See POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL for more information. + */ + const int INPUT_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL = 0x1000; + + /** * Common input event flag used for both motion and key events, indicating that the system has * detected this event may be inconsistent with the current event sequence or gesture, such as * when a pointer move event is sent but the pointer is not down. diff --git a/libs/input/android/os/InputConfig.aidl b/libs/input/android/os/InputConfig.aidl index da62e03821..e5f7b56561 100644 --- a/libs/input/android/os/InputConfig.aidl +++ b/libs/input/android/os/InputConfig.aidl @@ -57,16 +57,9 @@ enum InputConfig { NOT_TOUCHABLE = 1 << 3, /** - * Indicates that this window will not accept a touch event that is split between - * more than one window. When set: - * - If this window receives a DOWN event with the first pointer, all successive - * pointers that go down, regardless of their location on the screen, will be - * directed to this window; - * - If the DOWN event lands outside the touchable bounds of this window, no - * successive pointers that go down, regardless of their location on the screen, - * will be directed to this window. - */ - PREVENT_SPLITTING = 1 << 4, + * This flag is now deprecated and should not be used. + */ + DEPRECATED_PREVENT_SPLITTING = 1 << 4, /** * Indicates that this window shows the wallpaper behind it, so all touch events diff --git a/libs/input/android/os/MotionEventFlag.aidl b/libs/input/android/os/MotionEventFlag.aidl index 2093b0636a..6c9ccfbd04 100644 --- a/libs/input/android/os/MotionEventFlag.aidl +++ b/libs/input/android/os/MotionEventFlag.aidl @@ -118,13 +118,24 @@ enum MotionEventFlag { PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = 0x100, /** - * The input event was generated or modified by accessibility service. - * Shared by both KeyEvent and MotionEvent flags, so this value should not overlap with either - * set of flags, including in input/Input.h and in android/input.h. + * The input event was injected from some AccessibilityService, which may be either an + * Accessibility Tool OR a service using that API for purposes other than assisting users with + * disabilities. Shared by both KeyEvent and MotionEvent flags, so this value should not + * overlap with either set of flags, including in input/Input.h and in android/input.h. */ IS_ACCESSIBILITY_EVENT = IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT, /** + * The input event was injected from an AccessibilityService with the + * AccessibilityServiceInfo#isAccessibilityTool property set to true. These services (known as + * "Accessibility Tools") are used to assist users with disabilities, so events from these + * services should be able to reach all Views including Views which set + * View#isAccessibilityDataSensitive to true. Only used by MotionEvent flags. + */ + INJECTED_FROM_ACCESSIBILITY_TOOL = + IInputConstants.INPUT_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL, + + /** * Private flag that indicates when the system has detected that this motion event * may be inconsistent with respect to the sequence of previously delivered motion events, * such as when a pointer move event is sent but the pointer is not down. diff --git a/libs/input/input_flags.aconfig b/libs/input/input_flags.aconfig index 6cdd249b9e..983bbdee6e 100644 --- a/libs/input/input_flags.aconfig +++ b/libs/input/input_flags.aconfig @@ -16,10 +16,13 @@ flag { } flag { - name: "remove_input_channel_from_windowstate" + name: "enable_button_state_verification" namespace: "input" - description: "Do not store a copy of input channel inside WindowState." - bug: "323450804" + description: "Set to true to enable crashing whenever bad inbound events are going into InputDispatcher" + bug: "392870542" + metadata { + purpose: PURPOSE_BUGFIX + } } flag { @@ -37,9 +40,9 @@ flag { } flag { - name: "split_all_touches" + name: "deprecate_split_touch_apis" namespace: "input" - description: "Set FLAG_SPLIT_TOUCHES to true for all windows, regardless of what they specify. This is essentially deprecating this flag by forcefully enabling the split functionality" + description: "Deprecate all public APIs related to split touch because now all windows behave as if split touch is permanently enabled and there's no way for a window to disable split touch." bug: "239934827" } @@ -51,20 +54,6 @@ flag { } flag { - name: "report_palms_to_gestures_library" - namespace: "input" - description: "Report touches marked as palm by firmware to gestures library" - bug: "302505955" -} - -flag { - name: "enable_touchpad_typing_palm_rejection" - namespace: "input" - description: "Enabling additional touchpad palm rejection will disable the tap to click while the user is typing on a physical keyboard" - bug: "301055381" -} - -flag { name: "enable_v2_touchpad_typing_palm_rejection" namespace: "input" description: "In addition to touchpad palm rejection v1, v2 will also cancel ongoing move gestures while typing and add delay in re-enabling the tap to click." @@ -79,13 +68,6 @@ flag { } flag { - name: "enable_input_filter_rust_impl" - namespace: "input" - description: "Enable input filter rust implementation" - bug: "294546335" -} - -flag { name: "override_key_behavior_permission_apis" is_exported: true namespace: "input" @@ -131,13 +113,6 @@ flag { } flag { - name: "hide_pointer_indicators_for_secure_windows" - namespace: "input" - description: "Hide touch and pointer indicators if a secure window is present on display" - bug: "325252005" -} - -flag { name: "enable_keyboard_classifier" namespace: "input" description: "Keyboard classifier that classifies all keyboards into alphabetic or non-alphabetic" @@ -152,13 +127,6 @@ flag { } flag { - name: "include_relative_axis_values_for_captured_touchpads" - namespace: "input" - description: "Include AXIS_RELATIVE_X and AXIS_RELATIVE_Y values when reporting touches from captured touchpads." - bug: "330522990" -} - -flag { name: "enable_per_device_input_latency_metrics" namespace: "input" description: "Capture input latency metrics on a per device granular level using histograms." @@ -188,6 +156,16 @@ flag { } flag { + name: "disable_touch_input_mapper_pointer_usage" + namespace: "input" + description: "Disable the PointerUsage concept in TouchInputMapper since the old touchpad stack is no longer used." + bug: "281840344" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "keyboard_repeat_keys" namespace: "input" description: "Allow user to enable key repeats or configure timeout before key repeat and key repeat delay rates." @@ -224,3 +202,50 @@ flag { description: "Allow cursor to transition across multiple connected displays" bug: "362719483" } + +flag { + name: "connected_displays_associated_display_cursor_bugfix" + namespace: "lse_desktop_experience" + description: "Apply some rules to define associated display cursor behavior in connected displays" + bug: "396568321" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "use_cloned_screen_coordinates_as_raw" + namespace: "input" + description: "Use the cloned window's layer stack (screen) space as the raw coordinate space for input going to clones" + bug: "377846505" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "deprecate_uiautomation_input_injection" + namespace: "input" + description: "Deprecate UiAutomation#injectInputEvent and UiAutomation#injectInputEventToInputFilter test/hidden APIs" + bug: "277261245" +} + +flag { + name: "prevent_merging_input_pointer_devices" + namespace: "desktop_input" + description: "Prevent merging input sub-devices that provide pointer input streams" + bug: "389689566" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "enable_display_topology_validation" + namespace: "input" + description: "Set to true to enable display topology validation" + bug: "401219231" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/libs/input/rust/Android.bp b/libs/input/rust/Android.bp index 63853f77fa..fae9074c4d 100644 --- a/libs/input/rust/Android.bp +++ b/libs/input/rust/Android.bp @@ -18,12 +18,12 @@ rust_defaults { srcs: ["lib.rs"], host_supported: true, rustlibs: [ + "inputconstants-rust", "libbitflags", "libcxx", "libinput_bindgen", - "liblogger", "liblog_rust", - "inputconstants-rust", + "liblogger", "libserde", "libserde_json", ], diff --git a/libs/input/rust/input.rs b/libs/input/rust/input.rs index 90f509d97f..35ba04f5b6 100644 --- a/libs/input/rust/input.rs +++ b/libs/input/rust/input.rs @@ -50,7 +50,7 @@ pub enum SourceClass { bitflags! { /// Source of the input device or input events. - #[derive(Debug, PartialEq)] + #[derive(Clone, Copy, Debug, PartialEq)] pub struct Source: u32 { // Constants from SourceClass, added here for compatibility reasons /// SourceClass::Button @@ -101,6 +101,7 @@ bitflags! { /// A rust enum representation of a MotionEvent action. #[repr(u32)] +#[derive(Clone, Copy, Eq, PartialEq)] pub enum MotionAction { /// ACTION_DOWN Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN, @@ -131,9 +132,15 @@ pub enum MotionAction { /// ACTION_SCROLL Scroll = input_bindgen::AMOTION_EVENT_ACTION_SCROLL, /// ACTION_BUTTON_PRESS - ButtonPress = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, + ButtonPress { + /// The button being pressed. + action_button: MotionButton, + } = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, /// ACTION_BUTTON_RELEASE - ButtonRelease = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, + ButtonRelease { + /// The button being released. + action_button: MotionButton, + } = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, } impl fmt::Display for MotionAction { @@ -152,14 +159,20 @@ impl fmt::Display for MotionAction { MotionAction::Scroll => write!(f, "SCROLL"), MotionAction::HoverEnter => write!(f, "HOVER_ENTER"), MotionAction::HoverExit => write!(f, "HOVER_EXIT"), - MotionAction::ButtonPress => write!(f, "BUTTON_PRESS"), - MotionAction::ButtonRelease => write!(f, "BUTTON_RELEASE"), + MotionAction::ButtonPress { action_button } => { + write!(f, "BUTTON_PRESS({action_button:?})") + } + MotionAction::ButtonRelease { action_button } => { + write!(f, "BUTTON_RELEASE({action_button:?})") + } } } } -impl From<u32> for MotionAction { - fn from(action: u32) -> Self { +impl MotionAction { + /// Creates a [`MotionAction`] from an `AMOTION_EVENT_ACTION_…` constant and an action button + /// (which should be empty for all actions except `BUTTON_PRESS` and `…_RELEASE`). + pub fn from_code(action: u32, action_button: MotionButton) -> Self { let (action_masked, action_index) = MotionAction::breakdown_action(action); match action_masked { input_bindgen::AMOTION_EVENT_ACTION_DOWN => MotionAction::Down, @@ -177,14 +190,16 @@ impl From<u32> for MotionAction { input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE => MotionAction::HoverMove, input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT => MotionAction::HoverExit, input_bindgen::AMOTION_EVENT_ACTION_SCROLL => MotionAction::Scroll, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS => MotionAction::ButtonPress, - input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE => MotionAction::ButtonRelease, + input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS => { + MotionAction::ButtonPress { action_button } + } + input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE => { + MotionAction::ButtonRelease { action_button } + } _ => panic!("Unknown action: {}", action), } } -} -impl MotionAction { fn breakdown_action(action: u32) -> (u32, usize) { let action_masked = action & input_bindgen::AMOTION_EVENT_ACTION_MASK; let index = (action & input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) @@ -194,10 +209,31 @@ impl MotionAction { } bitflags! { + /// MotionEvent buttons. + #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] + pub struct MotionButton: u32 { + /// Primary button (e.g. the left mouse button) + const Primary = input_bindgen::AMOTION_EVENT_BUTTON_PRIMARY; + /// Secondary button (e.g. the right mouse button) + const Secondary = input_bindgen::AMOTION_EVENT_BUTTON_SECONDARY; + /// Tertiary button (e.g. the middle mouse button) + const Tertiary = input_bindgen::AMOTION_EVENT_BUTTON_TERTIARY; + /// Back button + const Back = input_bindgen::AMOTION_EVENT_BUTTON_BACK; + /// Forward button + const Forward = input_bindgen::AMOTION_EVENT_BUTTON_FORWARD; + /// Primary stylus button + const StylusPrimary = input_bindgen::AMOTION_EVENT_BUTTON_STYLUS_PRIMARY; + /// Secondary stylus button + const StylusSecondary = input_bindgen::AMOTION_EVENT_BUTTON_STYLUS_SECONDARY; + } +} + +bitflags! { /// MotionEvent flags. /// The source of truth for the flag definitions are the MotionEventFlag AIDL enum. /// The flag values are redefined here as a bitflags API. - #[derive(Debug)] + #[derive(Clone, Copy, Debug)] pub struct MotionFlags: u32 { /// FLAG_WINDOW_IS_OBSCURED const WINDOW_IS_OBSCURED = MotionEventFlag::WINDOW_IS_OBSCURED.0 as u32; @@ -219,6 +255,9 @@ bitflags! { MotionEventFlag::PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION.0 as u32; /// FLAG_IS_ACCESSIBILITY_EVENT const IS_ACCESSIBILITY_EVENT = MotionEventFlag::IS_ACCESSIBILITY_EVENT.0 as u32; + /// FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL + const INJECTED_FROM_ACCESSIBILITY_TOOL = + MotionEventFlag::INJECTED_FROM_ACCESSIBILITY_TOOL.0 as u32; /// FLAG_TAINTED const TAINTED = MotionEventFlag::TAINTED.0 as u32; /// FLAG_TARGET_ACCESSIBILITY_FOCUS diff --git a/libs/input/rust/input_verifier.rs b/libs/input/rust/input_verifier.rs index b1d7760682..f87dd413c6 100644 --- a/libs/input/rust/input_verifier.rs +++ b/libs/input/rust/input_verifier.rs @@ -17,21 +17,55 @@ //! Contains the InputVerifier, used to validate a stream of input events. use crate::ffi::RustPointerProperties; -use crate::input::{DeviceId, MotionAction, MotionFlags, Source, SourceClass}; +use crate::input::{DeviceId, MotionAction, MotionButton, MotionFlags, Source, SourceClass}; use log::info; use std::collections::HashMap; use std::collections::HashSet; -fn verify_event( - action: MotionAction, - pointer_properties: &[RustPointerProperties], - flags: &MotionFlags, -) -> Result<(), String> { - let pointer_count = pointer_properties.len(); +/// Represents a movement or state change event from a pointer device. The Rust equivalent of the +/// C++ NotifyMotionArgs struct. +#[derive(Clone, Copy)] +pub struct NotifyMotionArgs<'a> { + /// The ID of the device that emitted the event. + pub device_id: DeviceId, + + /// The type of device that emitted the event. + pub source: Source, + + /// The type of event that took place. + pub action: MotionAction, + + /// The properties of each of the pointers involved in the event. + pub pointer_properties: &'a [RustPointerProperties], + + /// Flags applied to the event. + pub flags: MotionFlags, + + /// The set of buttons that were pressed at the time of the event. + /// + /// We allow DOWN events to include buttons in their state for which BUTTON_PRESS events haven't + /// been sent yet. In that case, the DOWN should be immediately followed by BUTTON_PRESS events + /// for those buttons, building up to a button state matching that of the DOWN. For example, if + /// the user presses the primary and secondary buttons at exactly the same time, we'd expect + /// this sequence: + /// + /// | Action | Action button | Button state | + /// |----------------|---------------|------------------------| + /// | `HOVER_EXIT` | - | - | + /// | `DOWN` | - | `PRIMARY`, `SECONDARY` | + /// | `BUTTON_PRESS` | `PRIMARY` | `PRIMARY` | + /// | `BUTTON_PRESS` | `SECONDARY` | `PRIMARY`, `SECONDARY` | + /// | `MOVE` | - | `PRIMARY`, `SECONDARY` | + pub button_state: MotionButton, +} + +/// Verifies the properties of an event that should always be true, regardless of the current state. +fn verify_event(event: NotifyMotionArgs<'_>, verify_buttons: bool) -> Result<(), String> { + let pointer_count = event.pointer_properties.len(); if pointer_count < 1 { - return Err(format!("Invalid {} event: no pointers", action)); + return Err(format!("Invalid {} event: no pointers", event.action)); } - match action { + match event.action { MotionAction::Down | MotionAction::HoverEnter | MotionAction::HoverExit @@ -40,23 +74,40 @@ fn verify_event( if pointer_count != 1 { return Err(format!( "Invalid {} event: there are {} pointers in the event", - action, pointer_count + event.action, pointer_count )); } } MotionAction::Cancel => { - if !flags.contains(MotionFlags::CANCELED) { + if !event.flags.contains(MotionFlags::CANCELED) { return Err(format!( "For ACTION_CANCEL, must set FLAG_CANCELED. Received flags: {:#?}", - flags + event.flags )); } } MotionAction::PointerDown { action_index } | MotionAction::PointerUp { action_index } => { if action_index >= pointer_count { - return Err(format!("Got {}, but event has {} pointer(s)", action, pointer_count)); + return Err(format!( + "Got {}, but event has {} pointer(s)", + event.action, pointer_count + )); + } + } + + MotionAction::ButtonPress { action_button } + | MotionAction::ButtonRelease { action_button } => { + if verify_buttons { + let button_count = action_button.iter().count(); + if button_count != 1 { + return Err(format!( + "Invalid {} event: must specify a single action button, not {} action \ + buttons", + event.action, button_count + )); + } } } @@ -65,17 +116,94 @@ fn verify_event( Ok(()) } +/// Keeps track of the button state for a single device and verifies events against it. +#[derive(Default)] +struct ButtonVerifier { + /// The current button state of the device. + button_state: MotionButton, + + /// The set of "pending buttons", which were seen in the last DOWN event's button state but + /// for which we haven't seen BUTTON_PRESS events yet (see [`NotifyMotionArgs::button_state`]). + pending_buttons: MotionButton, +} + +impl ButtonVerifier { + pub fn process_event(&mut self, event: NotifyMotionArgs<'_>) -> Result<(), String> { + if !self.pending_buttons.is_empty() { + // We just saw a DOWN with some additional buttons in its state, so it should be + // immediately followed by ButtonPress events for those buttons. + match event.action { + MotionAction::ButtonPress { action_button } + if self.pending_buttons.contains(action_button) => + { + self.pending_buttons -= action_button; + } + _ => { + return Err(format!( + "After DOWN event, expected BUTTON_PRESS event(s) for {:?}, but got {}", + self.pending_buttons, event.action + )); + } + } + } + let expected_state = match event.action { + MotionAction::Down => { + if self.button_state - event.button_state != MotionButton::empty() { + return Err(format!( + "DOWN event button state is missing {:?}", + self.button_state - event.button_state + )); + } + self.pending_buttons = event.button_state - self.button_state; + // We've already checked that the state isn't missing any already-down buttons, and + // extra buttons are valid on DOWN actions, so bypass the expected state check. + event.button_state + } + MotionAction::ButtonPress { action_button } => { + if self.button_state.contains(action_button) { + return Err(format!( + "Duplicate BUTTON_PRESS; button state already contains {action_button:?}" + )); + } + self.button_state | action_button + } + MotionAction::ButtonRelease { action_button } => { + if !self.button_state.contains(action_button) { + return Err(format!( + "Invalid BUTTON_RELEASE; button state doesn't contain {action_button:?}", + )); + } + self.button_state - action_button + } + _ => self.button_state, + }; + if event.button_state != expected_state { + return Err(format!( + "Expected {} button state to be {:?}, but was {:?}", + event.action, expected_state, event.button_state + )); + } + // DOWN events can have pending buttons, so don't update the state for them. + if event.action != MotionAction::Down { + self.button_state = event.button_state; + } + Ok(()) + } +} + /// The InputVerifier is used to validate a stream of input events. pub struct InputVerifier { name: String, should_log: bool, + verify_buttons: bool, touching_pointer_ids_by_device: HashMap<DeviceId, HashSet<i32>>, hovering_pointer_ids_by_device: HashMap<DeviceId, HashSet<i32>>, + button_verifier_by_device: HashMap<DeviceId, ButtonVerifier>, } impl InputVerifier { /// Create a new InputVerifier. - pub fn new(name: &str, should_log: bool) -> Self { + pub fn new(name: &str, should_log: bool, verify_buttons: bool) -> Self { logger::init( logger::Config::default() .with_tag_on_device("InputVerifier") @@ -84,68 +212,70 @@ impl InputVerifier { Self { name: name.to_owned(), should_log, + verify_buttons, touching_pointer_ids_by_device: HashMap::new(), hovering_pointer_ids_by_device: HashMap::new(), + button_verifier_by_device: HashMap::new(), } } /// Process a pointer movement event from an InputDevice. /// If the event is not valid, we return an error string that describes the issue. - pub fn process_movement( - &mut self, - device_id: DeviceId, - source: Source, - action: u32, - pointer_properties: &[RustPointerProperties], - flags: MotionFlags, - ) -> Result<(), String> { - if !source.is_from_class(SourceClass::Pointer) { + pub fn process_movement(&mut self, event: NotifyMotionArgs<'_>) -> Result<(), String> { + if !event.source.is_from_class(SourceClass::Pointer) { // Skip non-pointer sources like MOUSE_RELATIVE for now return Ok(()); } if self.should_log { info!( "Processing {} for device {:?} ({} pointer{}) on {}", - MotionAction::from(action).to_string(), - device_id, - pointer_properties.len(), - if pointer_properties.len() == 1 { "" } else { "s" }, + event.action, + event.device_id, + event.pointer_properties.len(), + if event.pointer_properties.len() == 1 { "" } else { "s" }, self.name ); } - verify_event(action.into(), pointer_properties, &flags)?; + verify_event(event, self.verify_buttons)?; + + if self.verify_buttons { + self.button_verifier_by_device + .entry(event.device_id) + .or_default() + .process_event(event)?; + } - match action.into() { + match event.action { MotionAction::Down => { - if self.touching_pointer_ids_by_device.contains_key(&device_id) { + if self.touching_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{}: Invalid DOWN event - pointers already down for device {:?}: {:?}", - self.name, device_id, self.touching_pointer_ids_by_device + self.name, event.device_id, self.touching_pointer_ids_by_device )); } - let it = self.touching_pointer_ids_by_device.entry(device_id).or_default(); - it.insert(pointer_properties[0].id); + let it = self.touching_pointer_ids_by_device.entry(event.device_id).or_default(); + it.insert(event.pointer_properties[0].id); } MotionAction::PointerDown { action_index } => { - if !self.touching_pointer_ids_by_device.contains_key(&device_id) { + if !self.touching_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{}: Received POINTER_DOWN but no pointers are currently down \ for device {:?}", - self.name, device_id + self.name, event.device_id )); } - let it = self.touching_pointer_ids_by_device.get_mut(&device_id).unwrap(); - if it.len() != pointer_properties.len() - 1 { + let it = self.touching_pointer_ids_by_device.get_mut(&event.device_id).unwrap(); + if it.len() != event.pointer_properties.len() - 1 { return Err(format!( "{}: There are currently {} touching pointers, but the incoming \ POINTER_DOWN event has {}", self.name, it.len(), - pointer_properties.len() + event.pointer_properties.len() )); } - let pointer_id = pointer_properties[action_index].id; + let pointer_id = event.pointer_properties[action_index].id; if it.contains(&pointer_id) { return Err(format!( "{}: Pointer with id={} already present found in the properties", @@ -155,7 +285,7 @@ impl InputVerifier { it.insert(pointer_id); } MotionAction::Move => { - if !self.ensure_touching_pointers_match(device_id, pointer_properties) { + if !self.ensure_touching_pointers_match(event.device_id, event.pointer_properties) { return Err(format!( "{}: ACTION_MOVE touching pointers don't match", self.name @@ -163,49 +293,49 @@ impl InputVerifier { } } MotionAction::PointerUp { action_index } => { - if !self.ensure_touching_pointers_match(device_id, pointer_properties) { + if !self.ensure_touching_pointers_match(event.device_id, event.pointer_properties) { return Err(format!( "{}: ACTION_POINTER_UP touching pointers don't match", self.name )); } - let it = self.touching_pointer_ids_by_device.get_mut(&device_id).unwrap(); - let pointer_id = pointer_properties[action_index].id; + let it = self.touching_pointer_ids_by_device.get_mut(&event.device_id).unwrap(); + let pointer_id = event.pointer_properties[action_index].id; it.remove(&pointer_id); } MotionAction::Up => { - if !self.touching_pointer_ids_by_device.contains_key(&device_id) { + if !self.touching_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{} Received ACTION_UP but no pointers are currently down for device {:?}", - self.name, device_id + self.name, event.device_id )); } - let it = self.touching_pointer_ids_by_device.get_mut(&device_id).unwrap(); + let it = self.touching_pointer_ids_by_device.get_mut(&event.device_id).unwrap(); if it.len() != 1 { return Err(format!( "{}: Got ACTION_UP, but we have pointers: {:?} for device {:?}", - self.name, it, device_id + self.name, it, event.device_id )); } - let pointer_id = pointer_properties[0].id; + let pointer_id = event.pointer_properties[0].id; if !it.contains(&pointer_id) { return Err(format!( "{}: Got ACTION_UP, but pointerId {} is not touching. Touching pointers:\ {:?} for device {:?}", - self.name, pointer_id, it, device_id + self.name, pointer_id, it, event.device_id )); } - self.touching_pointer_ids_by_device.remove(&device_id); + self.touching_pointer_ids_by_device.remove(&event.device_id); } MotionAction::Cancel => { - if !self.ensure_touching_pointers_match(device_id, pointer_properties) { + if !self.ensure_touching_pointers_match(event.device_id, event.pointer_properties) { return Err(format!( "{}: Got ACTION_CANCEL, but the pointers don't match. \ Existing pointers: {:?}", self.name, self.touching_pointer_ids_by_device )); } - self.touching_pointer_ids_by_device.remove(&device_id); + self.touching_pointer_ids_by_device.remove(&event.device_id); } /* * The hovering protocol currently supports a single pointer only, because we do not @@ -214,41 +344,41 @@ impl InputVerifier { * eventually supported. */ MotionAction::HoverEnter => { - if self.hovering_pointer_ids_by_device.contains_key(&device_id) { + if self.hovering_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{}: Invalid HOVER_ENTER event - pointers already hovering for device {:?}:\ {:?}", - self.name, device_id, self.hovering_pointer_ids_by_device + self.name, event.device_id, self.hovering_pointer_ids_by_device )); } - let it = self.hovering_pointer_ids_by_device.entry(device_id).or_default(); - it.insert(pointer_properties[0].id); + let it = self.hovering_pointer_ids_by_device.entry(event.device_id).or_default(); + it.insert(event.pointer_properties[0].id); } MotionAction::HoverMove => { // For compatibility reasons, we allow HOVER_MOVE without a prior HOVER_ENTER. // If there was no prior HOVER_ENTER, just start a new hovering pointer. - let it = self.hovering_pointer_ids_by_device.entry(device_id).or_default(); - it.insert(pointer_properties[0].id); + let it = self.hovering_pointer_ids_by_device.entry(event.device_id).or_default(); + it.insert(event.pointer_properties[0].id); } MotionAction::HoverExit => { - if !self.hovering_pointer_ids_by_device.contains_key(&device_id) { + if !self.hovering_pointer_ids_by_device.contains_key(&event.device_id) { return Err(format!( "{}: Invalid HOVER_EXIT event - no pointers are hovering for device {:?}", - self.name, device_id + self.name, event.device_id )); } - let pointer_id = pointer_properties[0].id; - let it = self.hovering_pointer_ids_by_device.get_mut(&device_id).unwrap(); + let pointer_id = event.pointer_properties[0].id; + let it = self.hovering_pointer_ids_by_device.get_mut(&event.device_id).unwrap(); it.remove(&pointer_id); if !it.is_empty() { return Err(format!( "{}: Removed hovering pointer {}, but pointers are still\ hovering for device {:?}: {:?}", - self.name, pointer_id, device_id, it + self.name, pointer_id, event.device_id, it )); } - self.hovering_pointer_ids_by_device.remove(&device_id); + self.hovering_pointer_ids_by_device.remove(&event.device_id); } _ => return Ok(()), } @@ -288,295 +418,227 @@ impl InputVerifier { #[cfg(test)] mod tests { + use crate::input::MotionButton; use crate::input_verifier::InputVerifier; + use crate::input_verifier::NotifyMotionArgs; use crate::DeviceId; + use crate::MotionAction; use crate::MotionFlags; use crate::RustPointerProperties; use crate::Source; + const BASE_POINTER_PROPERTIES: [RustPointerProperties; 1] = [RustPointerProperties { id: 0 }]; + const BASE_EVENT: NotifyMotionArgs = NotifyMotionArgs { + device_id: DeviceId(1), + source: Source::Touchscreen, + action: MotionAction::Down, + pointer_properties: &BASE_POINTER_PROPERTIES, + flags: MotionFlags::empty(), + button_state: MotionButton::empty(), + }; + const BASE_MOUSE_EVENT: NotifyMotionArgs = + NotifyMotionArgs { source: Source::Mouse, ..BASE_EVENT }; + #[test] /** * Send a DOWN event with 2 pointers and ensure that it's marked as invalid. */ fn bad_down_event() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ true); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ true, /*verify_buttons*/ true); let pointer_properties = Vec::from([RustPointerProperties { id: 0 }, RustPointerProperties { id: 1 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_err()); } #[test] fn single_pointer_stream() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Move, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_UP, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Up, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); } #[test] fn two_pointer_stream() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); // POINTER 1 DOWN let two_pointer_properties = Vec::from([RustPointerProperties { id: 0 }, RustPointerProperties { id: 1 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN - | (1 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), - &two_pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::PointerDown { action_index: 1 }, + pointer_properties: &two_pointer_properties, + ..BASE_EVENT + }) .is_ok()); // POINTER 0 UP assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP - | (0 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), - &two_pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::PointerUp { action_index: 0 }, + pointer_properties: &two_pointer_properties, + ..BASE_EVENT + }) .is_ok()); // ACTION_UP for pointer id=1 let pointer_1_properties = Vec::from([RustPointerProperties { id: 1 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_UP, - &pointer_1_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Up, + pointer_properties: &pointer_1_properties, + ..BASE_EVENT + }) .is_ok()); } #[test] fn multi_device_stream() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(1), + action: MotionAction::Down, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(1), + action: MotionAction::Move, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(2), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(2), + action: MotionAction::Down, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(2), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(2), + action: MotionAction::Move, + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_UP, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(1), + action: MotionAction::Up, + ..BASE_EVENT + }) .is_ok()); } #[test] fn action_cancel() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + flags: MotionFlags::empty(), + ..BASE_EVENT + }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_CANCEL, - &pointer_properties, - MotionFlags::CANCELED, - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Cancel, + flags: MotionFlags::CANCELED, + ..BASE_EVENT + }) .is_ok()); } #[test] fn invalid_action_cancel() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - &pointer_properties, - MotionFlags::empty(), - ) - .is_ok()); - assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_CANCEL, - &pointer_properties, - MotionFlags::empty(), // forgot to set FLAG_CANCELED - ) + .process_movement(NotifyMotionArgs { action: MotionAction::Down, ..BASE_EVENT }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { action: MotionAction::Cancel, ..BASE_EVENT }) .is_err()); } #[test] fn invalid_up() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_UP, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { action: MotionAction::Up, ..BASE_EVENT }) .is_err()); } #[test] fn correct_hover_sequence() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverEnter, ..BASE_EVENT }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverMove, ..BASE_EVENT }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverExit, ..BASE_EVENT }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverEnter, ..BASE_EVENT }) .is_ok()); } #[test] fn double_hover_enter() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverEnter, ..BASE_EVENT }) .is_ok()); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { action: MotionAction::HoverEnter, ..BASE_EVENT }) .is_err()); } @@ -584,55 +646,356 @@ mod tests { // MOUSE_RELATIVE, which is used during pointer capture. The verifier should allow such event. #[test] fn relative_mouse_move() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); - let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); assert!(verifier - .process_movement( - DeviceId(2), - Source::MouseRelative, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + device_id: DeviceId(2), + source: Source::MouseRelative, + action: MotionAction::Move, + ..BASE_EVENT + }) .is_ok()); } // Send a MOVE event with incorrect number of pointers (one of the pointers is missing). #[test] fn move_with_wrong_number_of_pointers() { - let mut verifier = InputVerifier::new("Test", /*should_log*/ false); + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); let pointer_properties = Vec::from([RustPointerProperties { id: 0 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_DOWN, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) .is_ok()); // POINTER 1 DOWN let two_pointer_properties = Vec::from([RustPointerProperties { id: 0 }, RustPointerProperties { id: 1 }]); assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN - | (1 << input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), - &two_pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::PointerDown { action_index: 1 }, + pointer_properties: &two_pointer_properties, + ..BASE_EVENT + }) .is_ok()); // MOVE event with 1 pointer missing (the pointer with id = 1). It should be rejected assert!(verifier - .process_movement( - DeviceId(1), - Source::Touchscreen, - input_bindgen::AMOTION_EVENT_ACTION_MOVE, - &pointer_properties, - MotionFlags::empty(), - ) + .process_movement(NotifyMotionArgs { + action: MotionAction::Move, + pointer_properties: &pointer_properties, + ..BASE_EVENT + }) + .is_err()); + } + + #[test] + fn correct_button_press() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + } + + #[test] + fn button_press_without_action_button() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::empty() }, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn button_press_with_multiple_action_buttons() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { + action_button: MotionButton::Back | MotionButton::Forward + }, + button_state: MotionButton::Back | MotionButton::Forward, + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn button_press_without_action_button_in_state() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn button_release_with_action_button_in_state() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonRelease { action_button: MotionButton::Primary }, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn nonbutton_action_with_button_state_change() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::HoverEnter, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::HoverMove, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn nonbutton_action_missing_button_state() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::HoverEnter, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::HoverMove, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn up_without_button_release() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + // This UP event shouldn't change the button state; a BUTTON_RELEASE before it should. + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::Up, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn button_press_for_already_pressed_button() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn button_release_for_unpressed_button() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonRelease { action_button: MotionButton::Back }, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn correct_multiple_button_presses_without_down() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Forward }, + button_state: MotionButton::Back | MotionButton::Forward, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + } + + #[test] + fn correct_down_with_button_press() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + button_state: MotionButton::Primary | MotionButton::Secondary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Secondary }, + button_state: MotionButton::Primary | MotionButton::Secondary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + // Also check that the MOVE afterwards is OK, as that's where errors would be raised if not + // enough BUTTON_PRESSes were sent. + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::Move, + button_state: MotionButton::Primary | MotionButton::Secondary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + } + + #[test] + fn down_with_button_state_change_not_followed_by_button_press() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + // The DOWN event itself is OK, but it needs to be immediately followed by a BUTTON_PRESS. + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::Move, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn down_with_button_state_change_not_followed_by_enough_button_presses() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + button_state: MotionButton::Primary | MotionButton::Secondary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + // The DOWN event itself is OK, but it needs to be immediately followed by two + // BUTTON_PRESSes, one for each button. + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Primary }, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::Move, + button_state: MotionButton::Primary, + ..BASE_MOUSE_EVENT + }) + .is_err()); + } + + #[test] + fn down_missing_already_pressed_button() { + let mut verifier = + InputVerifier::new("Test", /*should_log*/ false, /*verify_buttons*/ true); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::ButtonPress { action_button: MotionButton::Back }, + button_state: MotionButton::Back, + ..BASE_MOUSE_EVENT + }) + .is_ok()); + assert!(verifier + .process_movement(NotifyMotionArgs { + action: MotionAction::Down, + button_state: MotionButton::empty(), + ..BASE_MOUSE_EVENT + }) .is_err()); } } diff --git a/libs/input/rust/keyboard_classification_config.rs b/libs/input/rust/keyboard_classification_config.rs index ab74efb674..26a8d8f4b8 100644 --- a/libs/input/rust/keyboard_classification_config.rs +++ b/libs/input/rust/keyboard_classification_config.rs @@ -20,6 +20,15 @@ use crate::input::KeyboardType; // key events at all. (Requires setup allowing InputDevice to dynamically add/remove // KeyboardInputMapper based on blocklist and KeyEvents in case a KeyboardType::None device ends // up producing a key event) + +/// This list pre-classifies a device into Alphabetic/Non-Alphabetic keyboard and tells us whether +/// further re-classification should be allowed or not (using is_finalized value). +/// This list DOES NOT change the source of the device or change the input mappers associated with +/// the device. It only changes the "KeyboardType" classification. This list should be primarily +/// used to pre-classify devices that are NOT keyboards(like mice, game pads, etc.) but generate +/// evdev nodes that say that they are alphabetic keyboards. +/// +/// NOTE: Pls keep the list sorted by vendor id and product id for easy searching. pub static CLASSIFIED_DEVICES: &[( /* vendorId */ u16, /* productId */ u16, @@ -96,6 +105,8 @@ pub static CLASSIFIED_DEVICES: &[( (0x056e, 0x0159, KeyboardType::NonAlphabetic, true), // Zebra LS2208 barcode scanner (0x05e0, 0x1200, KeyboardType::NonAlphabetic, true), + // Glorious O2 Wireless + (0x093a, 0x822d, KeyboardType::NonAlphabetic, true), // RDing FootSwitch1F1 (0x0c45, 0x7403, KeyboardType::NonAlphabetic, true), // SteelSeries Sensei RAW Frost Blue @@ -108,6 +119,8 @@ pub static CLASSIFIED_DEVICES: &[( (0x1050, 0x0010, KeyboardType::NonAlphabetic, true), // Yubico.com Yubikey 4 OTP+U2F+CCID (0x1050, 0x0407, KeyboardType::NonAlphabetic, true), + // Razer DeathAdder Essential + (0x1532, 0x0098, KeyboardType::NonAlphabetic, true), // Lenovo USB-C Wired Compact Mouse (0x17ef, 0x6123, KeyboardType::NonAlphabetic, true), // Corsair Katar Pro Wireless (USB dongle) diff --git a/libs/input/rust/keyboard_classifier.rs b/libs/input/rust/keyboard_classifier.rs index 3c789b41e2..1b89a5cf2b 100644 --- a/libs/input/rust/keyboard_classifier.rs +++ b/libs/input/rust/keyboard_classifier.rs @@ -66,11 +66,11 @@ impl KeyboardClassifier { /// Get keyboard type for a tracked keyboard in KeyboardClassifier pub fn get_keyboard_type(&self, device_id: DeviceId) -> KeyboardType { - return if let Some(keyboard) = self.device_map.get(&device_id) { + if let Some(keyboard) = self.device_map.get(&device_id) { keyboard.keyboard_type } else { KeyboardType::None - }; + } } /// Tells if keyboard type classification is finalized. Once finalized the classification can't @@ -79,11 +79,11 @@ impl KeyboardClassifier { /// Finalized devices are either "alphabetic" keyboards or keyboards in blocklist or /// allowlist that are explicitly categorized and won't change with future key events pub fn is_finalized(&self, device_id: DeviceId) -> bool { - return if let Some(keyboard) = self.device_map.get(&device_id) { + if let Some(keyboard) = self.device_map.get(&device_id) { keyboard.is_finalized } else { false - }; + } } /// Process a key event and change keyboard type if required. diff --git a/libs/input/rust/lib.rs b/libs/input/rust/lib.rs index 4f4ea8568b..ee999f7666 100644 --- a/libs/input/rust/lib.rs +++ b/libs/input/rust/lib.rs @@ -24,10 +24,10 @@ mod keyboard_classifier; pub use data_store::{DataStore, DefaultFileReaderWriter}; pub use input::{ - DeviceClass, DeviceId, InputDevice, KeyboardType, ModifierState, MotionAction, MotionFlags, - Source, + DeviceClass, DeviceId, InputDevice, KeyboardType, ModifierState, MotionAction, MotionButton, + MotionFlags, Source, }; -pub use input_verifier::InputVerifier; +pub use input_verifier::{InputVerifier, NotifyMotionArgs}; pub use keyboard_classifier::KeyboardClassifier; #[cxx::bridge(namespace = "android::input")] @@ -57,14 +57,17 @@ mod ffi { /// ``` type InputVerifier; #[cxx_name = create] - fn create_input_verifier(name: String) -> Box<InputVerifier>; + fn create_input_verifier(name: String, verify_buttons: bool) -> Box<InputVerifier>; + #[allow(clippy::too_many_arguments)] fn process_movement( verifier: &mut InputVerifier, device_id: i32, source: u32, action: u32, + action_button: u32, pointer_properties: &[RustPointerProperties], flags: u32, + button_state: u32, ) -> String; fn reset_device(verifier: &mut InputVerifier, device_id: i32); } @@ -115,33 +118,67 @@ mod ffi { use crate::ffi::{RustInputDeviceIdentifier, RustPointerProperties}; -fn create_input_verifier(name: String) -> Box<InputVerifier> { - Box::new(InputVerifier::new(&name, ffi::shouldLog("InputVerifierLogEvents"))) +fn create_input_verifier(name: String, verify_buttons: bool) -> Box<InputVerifier> { + Box::new(InputVerifier::new(&name, ffi::shouldLog("InputVerifierLogEvents"), verify_buttons)) } +#[allow(clippy::too_many_arguments)] fn process_movement( verifier: &mut InputVerifier, device_id: i32, source: u32, action: u32, + action_button: u32, pointer_properties: &[RustPointerProperties], flags: u32, + button_state: u32, ) -> String { - let motion_flags = MotionFlags::from_bits(flags); - if motion_flags.is_none() { + let Some(converted_source) = Source::from_bits(source) else { + panic!( + "The conversion of source 0x{source:08x} failed, please check if some sources have not \ + been added to Source." + ); + }; + let Some(motion_flags) = MotionFlags::from_bits(flags) else { panic!( "The conversion of flags 0x{:08x} failed, please check if some flags have not been \ added to MotionFlags.", flags ); + }; + let Some(motion_action_button) = MotionButton::from_bits(action_button) else { + panic!( + "The conversion of action button 0x{action_button:08x} failed, please check if some \ + buttons need to be added to MotionButton." + ); + }; + let Some(motion_button_state) = MotionButton::from_bits(button_state) else { + panic!( + "The conversion of button state 0x{button_state:08x} failed, please check if some \ + buttons need to be added to MotionButton." + ); + }; + let motion_action = MotionAction::from_code(action, motion_action_button); + if motion_action_button != MotionButton::empty() { + match motion_action { + MotionAction::ButtonPress { action_button: _ } + | MotionAction::ButtonRelease { action_button: _ } => {} + _ => { + return format!( + "Invalid {motion_action} event: has action button {motion_action_button:?} but \ + is not a button action" + ); + } + } } - let result = verifier.process_movement( - DeviceId(device_id), - Source::from_bits(source).unwrap(), - action, + let result = verifier.process_movement(NotifyMotionArgs { + device_id: DeviceId(device_id), + source: converted_source, + action: motion_action, pointer_properties, - motion_flags.unwrap(), - ); + flags: motion_flags, + button_state: motion_button_state, + }); match result { Ok(()) => "".to_string(), Err(e) => e, @@ -208,3 +245,44 @@ fn process_key( } classifier.process_key(DeviceId(device_id), evdev_code, modifier_state.unwrap()); } + +#[cfg(test)] +mod tests { + use crate::create_input_verifier; + use crate::process_movement; + use crate::RustPointerProperties; + + const BASE_POINTER_PROPERTIES: [RustPointerProperties; 1] = [RustPointerProperties { id: 0 }]; + + #[test] + fn verify_nonbutton_action_with_action_button() { + let mut verifier = create_input_verifier("Test".to_string(), /*verify_buttons*/ true); + assert!(process_movement( + &mut verifier, + 1, + input_bindgen::AINPUT_SOURCE_MOUSE, + input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + input_bindgen::AMOTION_EVENT_BUTTON_PRIMARY, + &BASE_POINTER_PROPERTIES, + 0, + 0, + ) + .contains("button action")); + } + + #[test] + fn verify_nonbutton_action_with_action_button_and_button_state() { + let mut verifier = create_input_verifier("Test".to_string(), /*verify_buttons*/ true); + assert!(process_movement( + &mut verifier, + 1, + input_bindgen::AINPUT_SOURCE_MOUSE, + input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, + input_bindgen::AMOTION_EVENT_BUTTON_PRIMARY, + &BASE_POINTER_PROPERTIES, + 0, + input_bindgen::AMOTION_EVENT_BUTTON_PRIMARY, + ) + .contains("button action")); + } +} diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp index 85a37fe04a..968fa5fc1a 100644 --- a/libs/input/tests/Android.bp +++ b/libs/input/tests/Android.bp @@ -16,16 +16,16 @@ cc_test { "BlockingQueue_test.cpp", "IdGenerator_test.cpp", "InputChannel_test.cpp", - "InputConsumer_test.cpp", "InputConsumerFilteredResampling_test.cpp", "InputConsumerResampling_test.cpp", + "InputConsumer_test.cpp", "InputDevice_test.cpp", "InputEvent_test.cpp", - "InputPublisherAndConsumer_test.cpp", "InputPublisherAndConsumerNoResampling_test.cpp", + "InputPublisherAndConsumer_test.cpp", "InputVerifier_test.cpp", - "MotionPredictor_test.cpp", "MotionPredictorMetricsManager_test.cpp", + "MotionPredictor_test.cpp", "OneEuroFilter_test.cpp", "Resampler_test.cpp", "RingBuffer_test.cpp", @@ -53,8 +53,8 @@ cc_test { ], cflags: [ "-Wall", - "-Wextra", "-Werror", + "-Wextra", "-Wno-unused-parameter", ], sanitize: { @@ -68,26 +68,26 @@ cc_test { memtag_heap: true, undefined: true, misc_undefined: [ - "bounds", "all", + "bounds", ], }, }, shared_libs: [ + "libPlatformProperties", "libaconfig_storage_read_api_cc", "libbase", "libbinder", "libcutils", "liblog", - "libPlatformProperties", "libstatslog", "libtinyxml2", "libutils", "server_configurable_flags", ], data: [ - "data/*", ":motion_predictor_model", + "data/*", ], test_options: { unit_test: true, @@ -117,10 +117,10 @@ cc_library_static { "-Wextra", ], shared_libs: [ - "libinput", + "libbase", + "libbinder", "libcutils", + "libinput", "libutils", - "libbinder", - "libbase", ], } diff --git a/libs/input/tests/InputVerifier_test.cpp b/libs/input/tests/InputVerifier_test.cpp index e2eb08096b..8e0d9068c1 100644 --- a/libs/input/tests/InputVerifier_test.cpp +++ b/libs/input/tests/InputVerifier_test.cpp @@ -14,9 +14,13 @@ * limitations under the License. */ +#include <android/input.h> +#include <android-base/result.h> #include <gtest/gtest.h> +#include <input/Input.h> #include <input/InputVerifier.h> #include <string> +#include <vector> namespace android { @@ -45,10 +49,10 @@ TEST(InputVerifierTest, ProcessSourceClassPointer) { const Result<void> result = verifier.processMovement(/*deviceId=*/0, AINPUT_SOURCE_CLASS_POINTER, - AMOTION_EVENT_ACTION_DOWN, + AMOTION_EVENT_ACTION_DOWN, /*actionButton=*/0, /*pointerCount=*/properties.size(), properties.data(), - coords.data(), /*flags=*/0); - ASSERT_TRUE(result.ok()); + coords.data(), /*flags=*/0, /*buttonState=*/0); + ASSERT_RESULT_OK(result); } } // namespace android diff --git a/libs/input/tests/TestEventMatchers.h b/libs/input/tests/TestEventMatchers.h index 56eaefd074..8dbdcb310a 100644 --- a/libs/input/tests/TestEventMatchers.h +++ b/libs/input/tests/TestEventMatchers.h @@ -27,12 +27,8 @@ namespace android { -namespace { - using ::testing::Matcher; -} // namespace - /** * This file contains a copy of Matchers from .../inputflinger/tests/TestEventMatchers.h. Ideally, * implementations must not be duplicated. diff --git a/libs/math/OWNERS b/libs/math/OWNERS index 82ae422893..08f0c5f0dc 100644 --- a/libs/math/OWNERS +++ b/libs/math/OWNERS @@ -1,5 +1,4 @@ mathias@google.com -randolphs@google.com romainguy@google.com sumir@google.com jreck@google.com diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp index bed31e27a8..89a97deffd 100644 --- a/libs/nativedisplay/AChoreographer.cpp +++ b/libs/nativedisplay/AChoreographer.cpp @@ -142,7 +142,7 @@ static inline AChoreographer* Choreographer_to_AChoreographer(Choreographer* cho } AChoreographer* AChoreographer_getInstance() { - return Choreographer_to_AChoreographer(Choreographer::getForThread()); + return Choreographer_to_AChoreographer(Choreographer::getForThread().get()); } void AChoreographer_postFrameCallback(AChoreographer* choreographer, @@ -238,13 +238,17 @@ int64_t AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos( } AChoreographer* AChoreographer_create() { - Choreographer* choreographer = new Choreographer(nullptr); + // Increments default strongRef count on construction, will be decremented on + // function exit. + auto choreographer = sp<Choreographer>::make(nullptr); status_t result = choreographer->initialize(); if (result != OK) { ALOGW("Failed to initialize"); return nullptr; } - return Choreographer_to_AChoreographer(choreographer); + // Will be decremented and destroyed by AChoreographer_destroy + choreographer->incStrong((void*)AChoreographer_create); + return Choreographer_to_AChoreographer(choreographer.get()); } void AChoreographer_destroy(AChoreographer* choreographer) { @@ -252,7 +256,7 @@ void AChoreographer_destroy(AChoreographer* choreographer) { return; } - delete AChoreographer_to_Choreographer(choreographer); + AChoreographer_to_Choreographer(choreographer)->decStrong((void*)AChoreographer_create); } int AChoreographer_getFd(const AChoreographer* choreographer) { diff --git a/libs/nativedisplay/include/surfacetexture/EGLConsumer.h b/libs/nativedisplay/include/surfacetexture/EGLConsumer.h index 444722bf83..226a8a60af 100644 --- a/libs/nativedisplay/include/surfacetexture/EGLConsumer.h +++ b/libs/nativedisplay/include/surfacetexture/EGLConsumer.h @@ -113,18 +113,11 @@ public: protected: struct PendingRelease { - PendingRelease() - : isPending(false), - currentTexture(-1), - graphicBuffer(), - display(nullptr), - fence(nullptr) {} + PendingRelease() : isPending(false), currentTexture(-1), graphicBuffer() {} bool isPending; int currentTexture; sp<GraphicBuffer> graphicBuffer; - EGLDisplay display; - EGLSyncKHR fence; }; /** @@ -250,13 +243,16 @@ protected: * EGLConsumer maintains about a BufferQueue buffer slot. */ struct EglSlot { - EglSlot() : mEglFence(EGL_NO_SYNC_KHR) {} +#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + EglSlot() : mEglFence(EGL_NO_SYNC_KHR) {} +#endif /** * mEglImage is the EGLImage created from mGraphicBuffer. */ sp<EglImage> mEglImage; +#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) /** * mFence is the EGL sync object that must signal before the buffer * associated with this buffer slot may be dequeued. It is initialized @@ -264,6 +260,7 @@ protected: * on a compile-time option) set to a new sync object in updateTexImage. */ EGLSyncKHR mEglFence; +#endif }; /** diff --git a/libs/nativedisplay/include/surfacetexture/SurfaceTexture.h b/libs/nativedisplay/include/surfacetexture/SurfaceTexture.h index 006a785cb7..253aa18a24 100644 --- a/libs/nativedisplay/include/surfacetexture/SurfaceTexture.h +++ b/libs/nativedisplay/include/surfacetexture/SurfaceTexture.h @@ -343,9 +343,13 @@ protected: * releaseBufferLocked overrides the ConsumerBase method to update the * mEglSlots array in addition to the ConsumerBase. */ +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + virtual status_t releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer) override; +#else virtual status_t releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer, EGLDisplay display = EGL_NO_DISPLAY, EGLSyncKHR eglFence = EGL_NO_SYNC_KHR) override; +#endif /** * freeBufferLocked frees up the given buffer slot. If the slot has been diff --git a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp index 3959fce008..fad0f6cd0b 100644 --- a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp +++ b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp @@ -221,7 +221,11 @@ void EGLConsumer::onAcquireBufferLocked(BufferItem* item, SurfaceTexture& st) { } void EGLConsumer::onReleaseBufferLocked(int buf) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + (void)buf; +#else mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; +#endif } status_t EGLConsumer::updateAndReleaseLocked(const BufferItem& item, PendingRelease* pendingRelease, @@ -283,10 +287,15 @@ status_t EGLConsumer::updateAndReleaseLocked(const BufferItem& item, PendingRele // release old buffer if (st.mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (pendingRelease == nullptr) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + status_t status = st.releaseBufferLocked(st.mCurrentTexture, + mCurrentTextureImage->graphicBuffer()); +#else status_t status = st.releaseBufferLocked(st.mCurrentTexture, mCurrentTextureImage->graphicBuffer(), mEglDisplay, mEglSlots[st.mCurrentTexture].mEglFence); +#endif if (status < NO_ERROR) { EGC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status), status); @@ -296,8 +305,6 @@ status_t EGLConsumer::updateAndReleaseLocked(const BufferItem& item, PendingRele } else { pendingRelease->currentTexture = st.mCurrentTexture; pendingRelease->graphicBuffer = mCurrentTextureImage->graphicBuffer(); - pendingRelease->display = mEglDisplay; - pendingRelease->fence = mEglSlots[st.mCurrentTexture].mEglFence; pendingRelease->isPending = true; } } @@ -502,6 +509,11 @@ status_t EGLConsumer::syncForReleaseLocked(EGLDisplay dpy, SurfaceTexture& st) { return err; } } else if (st.mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + // Basically all clients are using native fence syncs. If they aren't, we lose nothing + // by waiting here, because the alternative can cause deadlocks (b/339705065). + glFinish(); +#else EGLSyncKHR fence = mEglSlots[st.mCurrentTexture].mEglFence; if (fence != EGL_NO_SYNC_KHR) { // There is already a fence for the current slot. We need to @@ -531,6 +543,7 @@ status_t EGLConsumer::syncForReleaseLocked(EGLDisplay dpy, SurfaceTexture& st) { } glFlush(); mEglSlots[st.mCurrentTexture].mEglFence = fence; +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) } } diff --git a/libs/nativedisplay/surfacetexture/ImageConsumer.cpp b/libs/nativedisplay/surfacetexture/ImageConsumer.cpp index 60e87b54d5..1ffd382b80 100644 --- a/libs/nativedisplay/surfacetexture/ImageConsumer.cpp +++ b/libs/nativedisplay/surfacetexture/ImageConsumer.cpp @@ -14,6 +14,10 @@ * limitations under the License. */ +#define EGL_EGLEXT_PROTOTYPES +#include <EGL/egl.h> +#include <EGL/eglext.h> + #include <gui/BufferQueue.h> #include <surfacetexture/ImageConsumer.h> #include <surfacetexture/SurfaceTexture.h> @@ -95,10 +99,34 @@ sp<GraphicBuffer> ImageConsumer::dequeueBuffer(int* outSlotid, android_dataspace } // Finally release the old buffer. +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + EGLSyncKHR previousFence = mImageSlots[st.mCurrentTexture].eglFence(); + if (previousFence != EGL_NO_SYNC_KHR) { + // Most platforms will be using native fences, so it's unlikely that we'll ever have to + // process an eglFence. Ideally we can remove this code eventually. In the mean time, do + // our best to wait for it so the buffer stays valid, otherwise return an error to the + // caller. + // + // EGL_SYNC_FLUSH_COMMANDS_BIT_KHR so that we don't wait forever on a fence that hasn't + // shown up on the GPU yet. + EGLint result = eglClientWaitSyncKHR(display, previousFence, + EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 1000000000); + if (result == EGL_FALSE) { + IMG_LOGE("dequeueBuffer: error %#x waiting for fence", eglGetError()); + } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { + IMG_LOGE("dequeueBuffer: timeout waiting for fence"); + } + eglDestroySyncKHR(display, previousFence); + } + + status_t status = st.releaseBufferLocked(st.mCurrentTexture, + st.mSlots[st.mCurrentTexture].mGraphicBuffer); +#else status_t status = st.releaseBufferLocked(st.mCurrentTexture, st.mSlots[st.mCurrentTexture].mGraphicBuffer, display, mImageSlots[st.mCurrentTexture].eglFence()); +#endif if (status < NO_ERROR) { IMG_LOGE("dequeueImage: failed to release buffer: %s (%d)", strerror(-status), status); err = status; diff --git a/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp b/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp index ce232cc4c7..c0a1cc5c36 100644 --- a/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp +++ b/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp @@ -178,13 +178,21 @@ status_t SurfaceTexture::acquireBufferLocked(BufferItem* item, nsecs_t presentWh return NO_ERROR; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) +status_t SurfaceTexture::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicBuffer) { +#else status_t SurfaceTexture::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicBuffer, EGLDisplay display, EGLSyncKHR eglFence) { +#endif // release the buffer if it hasn't already been discarded by the // BufferQueue. This can happen, for example, when the producer of this // buffer has reallocated the original buffer slot after this buffer // was acquired. +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) + status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer); +#else status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer, display, eglFence); +#endif // We could be releasing an EGL/Vulkan buffer, even if not currently // attached to a GL context. mImageConsumer.onReleaseBufferLocked(buf); diff --git a/libs/nativewindow/rust/src/lib.rs b/libs/nativewindow/rust/src/lib.rs index d760285918..aeb26031a5 100644 --- a/libs/nativewindow/rust/src/lib.rs +++ b/libs/nativewindow/rust/src/lib.rs @@ -541,7 +541,7 @@ pub struct HardwareBufferGuard<'a> { pub address: NonNull<c_void>, } -impl<'a> Drop for HardwareBufferGuard<'a> { +impl Drop for HardwareBufferGuard<'_> { fn drop(&mut self) { self.buffer .unlock() diff --git a/libs/nativewindow/tests/ANativeWindowTest.cpp b/libs/nativewindow/tests/ANativeWindowTest.cpp index 937ff02241..51d0c8195a 100644 --- a/libs/nativewindow/tests/ANativeWindowTest.cpp +++ b/libs/nativewindow/tests/ANativeWindowTest.cpp @@ -50,14 +50,9 @@ protected: const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); ALOGV("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) - mItemConsumer = new BufferItemConsumer(GRALLOC_USAGE_SW_READ_OFTEN); - mWindow = new TestableSurface(mItemConsumer->getSurface()->getIGraphicBufferProducer()); -#else - BufferQueue::createBufferQueue(&mProducer, &mConsumer); - mItemConsumer = new BufferItemConsumer(mConsumer, GRALLOC_USAGE_SW_READ_OFTEN); - mWindow = new TestableSurface(mProducer); -#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) + sp<Surface> surface; + std::tie(mItemConsumer, surface) = BufferItemConsumer::create(GRALLOC_USAGE_SW_READ_OFTEN); + mWindow = new TestableSurface(surface->getIGraphicBufferProducer()); const int success = native_window_api_connect(mWindow.get(), NATIVE_WINDOW_API_CPU); EXPECT_EQ(0, success); } diff --git a/libs/permission/Android.bp b/libs/permission/Android.bp index 0eeca5469e..929f067bcd 100644 --- a/libs/permission/Android.bp +++ b/libs/permission/Android.bp @@ -16,6 +16,7 @@ aidl_interface { double_loadable: true, srcs: [ "aidl/android/content/AttributionSourceState.aidl", + "aidl/com/android/internal/app/IAppOpsCallback.aidl", "aidl/android/permission/IPermissionChecker.aidl", ], } @@ -36,7 +37,6 @@ cc_library { ], srcs: [ "AppOpsManager.cpp", - "IAppOpsCallback.cpp", "IAppOpsService.cpp", "android/permission/PermissionChecker.cpp", ], diff --git a/libs/permission/IAppOpsCallback.cpp b/libs/permission/IAppOpsCallback.cpp deleted file mode 100644 index 2b3f462ab8..0000000000 --- a/libs/permission/IAppOpsCallback.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "AppOpsCallback" - -#include <binder/IAppOpsCallback.h> - -#include <utils/Log.h> -#include <binder/Parcel.h> -#include <utils/String8.h> - -namespace android { - -// ---------------------------------------------------------------------- - -class BpAppOpsCallback : public BpInterface<IAppOpsCallback> -{ -public: - explicit BpAppOpsCallback(const sp<IBinder>& impl) - : BpInterface<IAppOpsCallback>(impl) - { - } - - virtual void opChanged(int32_t op, const String16& packageName) { - Parcel data, reply; - data.writeInterfaceToken(IAppOpsCallback::getInterfaceDescriptor()); - data.writeInt32(op); - data.writeString16(packageName); - remote()->transact(OP_CHANGED_TRANSACTION, data, &reply, IBinder::FLAG_ONEWAY); - } -}; - -IMPLEMENT_META_INTERFACE(AppOpsCallback, "com.android.internal.app.IAppOpsCallback") - -// ---------------------------------------------------------------------- - -// NOLINTNEXTLINE(google-default-arguments) -status_t BnAppOpsCallback::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch(code) { - case OP_CHANGED_TRANSACTION: { - CHECK_INTERFACE(IAppOpsCallback, data, reply); - int32_t op = data.readInt32(); - String16 packageName; - (void)data.readString16(&packageName); - opChanged(op, packageName); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -} // namespace android diff --git a/libs/permission/aidl/com/android/internal/app/IAppOpsCallback.aidl b/libs/permission/aidl/com/android/internal/app/IAppOpsCallback.aidl new file mode 100644 index 0000000000..36b19dfb25 --- /dev/null +++ b/libs/permission/aidl/com/android/internal/app/IAppOpsCallback.aidl @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.app; + +oneway interface IAppOpsCallback { + void opChanged(int op, int uid, String packageName, String persistentDeviceId); +} diff --git a/libs/permission/include/binder/AppOpsManager.h b/libs/permission/include/binder/AppOpsManager.h index 7e179d6f7c..a22c975588 100644 --- a/libs/permission/include/binder/AppOpsManager.h +++ b/libs/permission/include/binder/AppOpsManager.h @@ -180,10 +180,10 @@ public: void finishOp(int32_t op, int32_t uid, const String16& callingPackage, const std::optional<String16>& attributionTag); void startWatchingMode(int32_t op, const String16& packageName, - const sp<IAppOpsCallback>& callback); + const sp<com::android::internal::app::IAppOpsCallback>& callback); void startWatchingMode(int32_t op, const String16& packageName, int32_t flags, - const sp<IAppOpsCallback>& callback); - void stopWatchingMode(const sp<IAppOpsCallback>& callback); + const sp<com::android::internal::app::IAppOpsCallback>& callback); + void stopWatchingMode(const sp<com::android::internal::app::IAppOpsCallback>& callback); int32_t permissionToOpCode(const String16& permission); void setCameraAudioRestriction(int32_t mode); diff --git a/libs/permission/include/binder/IAppOpsCallback.h b/libs/permission/include/binder/IAppOpsCallback.h deleted file mode 100644 index eb76f57bf8..0000000000 --- a/libs/permission/include/binder/IAppOpsCallback.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#ifndef __ANDROID_VNDK__ - -#include <binder/IInterface.h> - -namespace android { - -// ---------------------------------------------------------------------- - -class IAppOpsCallback : public IInterface -{ -public: - DECLARE_META_INTERFACE(AppOpsCallback) - - virtual void opChanged(int32_t op, const String16& packageName) = 0; - - enum { - OP_CHANGED_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION - }; -}; - -// ---------------------------------------------------------------------- - -class BnAppOpsCallback : public BnInterface<IAppOpsCallback> -{ -public: - // NOLINTNEXTLINE(google-default-arguments) - virtual status_t onTransact( uint32_t code, - const Parcel& data, - Parcel* reply, - uint32_t flags = 0); -}; - -// ---------------------------------------------------------------------- - -} // namespace android - -#else // __ANDROID_VNDK__ -#error "This header is not visible to vendors" -#endif // __ANDROID_VNDK__ diff --git a/libs/permission/include/binder/IAppOpsService.h b/libs/permission/include/binder/IAppOpsService.h index 918fcdbce1..1468fd9415 100644 --- a/libs/permission/include/binder/IAppOpsService.h +++ b/libs/permission/include/binder/IAppOpsService.h @@ -16,7 +16,8 @@ #pragma once -#include <binder/IAppOpsCallback.h> +#include <com/android/internal/app/IAppOpsCallback.h> +#include <com/android/internal/app/BnAppOpsCallback.h> #include <binder/IInterface.h> #include <optional> @@ -27,6 +28,8 @@ namespace android { +using IAppOpsCallback = ::com::android::internal::app::IAppOpsCallback; + // ---------------------------------------------------------------------- class IAppOpsService : public IInterface diff --git a/libs/renderengine/OWNERS b/libs/renderengine/OWNERS index 17ab29fd29..e296283f26 100644 --- a/libs/renderengine/OWNERS +++ b/libs/renderengine/OWNERS @@ -7,4 +7,3 @@ jreck@google.com lpy@google.com nscobie@google.com sallyqi@google.com -scroggo@google.com diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h index ac43da8dcf..ecb16b2e17 100644 --- a/libs/renderengine/include/renderengine/LayerSettings.h +++ b/libs/renderengine/include/renderengine/LayerSettings.h @@ -301,6 +301,10 @@ static inline void PrintTo(const LayerSettings& settings, ::std::ostream* os) { *os << "\n .edgeExtensionEffect = " << settings.edgeExtensionEffect; } *os << "\n .whitePointNits = " << settings.whitePointNits; + if (settings.luts) { + *os << "\n .luts = "; + PrintTo(settings.luts, os); + } *os << "\n}"; } diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp index 57041ee6a1..f43694e228 100644 --- a/libs/renderengine/skia/Cache.cpp +++ b/libs/renderengine/skia/Cache.cpp @@ -14,6 +14,9 @@ * limitations under the License. */ #include "Cache.h" + +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + #include "AutoBackendTexture.h" #include "SkiaRenderEngine.h" #include "android-base/unique_fd.h" @@ -28,6 +31,7 @@ #include "utils/Timers.h" #include <com_android_graphics_libgui_flags.h> +#include <common/trace.h> namespace android::renderengine::skia { @@ -337,17 +341,17 @@ static void drawImageDimmedLayers(SkiaRenderEngine* renderengine, const DisplayS LayerSettings layer{ .geometry = Geometry{ + .boundaries = rect, // The position transform doesn't matter when the reduced shader mode // in in effect. A matrix transform stage is always included. .positionTransform = mat4(), - .boundaries = rect, - .roundedCornersCrop = rect, .roundedCornersRadius = {0.f, 0.f}, + .roundedCornersCrop = rect, }, .source = PixelSource{.buffer = Buffer{.buffer = srcTexture, - .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, - .isOpaque = true}}, + .isOpaque = true, + .maxLuminanceNits = 1000.f}}, .alpha = 1.f, .sourceDataspace = kDestDataSpace, }; @@ -370,16 +374,16 @@ static void drawTransparentImageDimmedLayers(SkiaRenderEngine* renderengine, LayerSettings layer{ .geometry = Geometry{ - .positionTransform = mat4(), .boundaries = rect, + .positionTransform = mat4(), .roundedCornersCrop = rect, }, .source = PixelSource{.buffer = Buffer{ .buffer = srcTexture, - .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, .isOpaque = false, + .maxLuminanceNits = 1000.f, }}, .sourceDataspace = kDestDataSpace, }; @@ -421,17 +425,17 @@ static void drawClippedDimmedImageLayers(SkiaRenderEngine* renderengine, LayerSettings layer{ .geometry = Geometry{ - .positionTransform = mat4(), .boundaries = boundary, - .roundedCornersCrop = rect, + .positionTransform = mat4(), .roundedCornersRadius = {27.f, 27.f}, + .roundedCornersCrop = rect, }, .source = PixelSource{.buffer = Buffer{ .buffer = srcTexture, - .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, .isOpaque = false, + .maxLuminanceNits = 1000.f, }}, .alpha = 1.f, .sourceDataspace = kDestDataSpace, @@ -489,17 +493,17 @@ static void drawBT2020ImageLayers(SkiaRenderEngine* renderengine, const DisplayS LayerSettings layer{ .geometry = Geometry{ + .boundaries = rect, // The position transform doesn't matter when the reduced shader mode // in in effect. A matrix transform stage is always included. .positionTransform = mat4(), - .boundaries = rect, - .roundedCornersCrop = rect, .roundedCornersRadius = {0.f, 0.f}, + .roundedCornersCrop = rect, }, .source = PixelSource{.buffer = Buffer{.buffer = srcTexture, - .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, - .isOpaque = true}}, + .isOpaque = true, + .maxLuminanceNits = 1000.f}}, .alpha = 1.f, .sourceDataspace = kBT2020DataSpace, }; @@ -527,17 +531,17 @@ static void drawBT2020ClippedImageLayers(SkiaRenderEngine* renderengine, LayerSettings layer{ .geometry = Geometry{ - .positionTransform = kScaleAsymmetric, .boundaries = boundary, - .roundedCornersCrop = rect, + .positionTransform = kScaleAsymmetric, .roundedCornersRadius = {64.1f, 64.1f}, + .roundedCornersCrop = rect, }, .source = PixelSource{.buffer = Buffer{ .buffer = srcTexture, - .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, .isOpaque = true, + .maxLuminanceNits = 1000.f, }}, .alpha = 0.5f, .sourceDataspace = kBT2020DataSpace, @@ -556,17 +560,17 @@ static void drawExtendedHDRImageLayers(SkiaRenderEngine* renderengine, LayerSettings layer{ .geometry = Geometry{ + .boundaries = rect, // The position transform doesn't matter when the reduced shader mode // in in effect. A matrix transform stage is always included. .positionTransform = mat4(), - .boundaries = rect, - .roundedCornersCrop = rect, .roundedCornersRadius = {50.f, 50.f}, + .roundedCornersCrop = rect, }, .source = PixelSource{.buffer = Buffer{.buffer = srcTexture, - .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, - .isOpaque = true}}, + .isOpaque = true, + .maxLuminanceNits = 1000.f}}, .alpha = 0.5f, .sourceDataspace = kExtendedHdrDataSpce, }; @@ -594,17 +598,17 @@ static void drawP3ImageLayers(SkiaRenderEngine* renderengine, const DisplaySetti LayerSettings layer{ .geometry = Geometry{ + .boundaries = rect, // The position transform doesn't matter when the reduced shader mode // in in effect. A matrix transform stage is always included. .positionTransform = mat4(), - .boundaries = rect, - .roundedCornersCrop = rect, .roundedCornersRadius = {50.f, 50.f}, + .roundedCornersCrop = rect, }, .source = PixelSource{.buffer = Buffer{.buffer = srcTexture, - .maxLuminanceNits = 1000.f, .usePremultipliedAlpha = true, - .isOpaque = false}}, + .isOpaque = false, + .maxLuminanceNits = 1000.f}}, .alpha = 0.5f, .sourceDataspace = kOtherDataSpace, }; @@ -659,6 +663,7 @@ static void drawEdgeExtensionLayers(SkiaRenderEngine* renderengine, const Displa // in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp // gPrintSKSL = true void Cache::primeShaderCache(SkiaRenderEngine* renderengine, PrimeCacheConfig config) { + SFTRACE_CALL(); const int previousCount = renderengine->reportShadersCompiled(); if (previousCount) { ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount); @@ -724,24 +729,29 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine, PrimeCacheConfig co impl::ExternalTexture::Usage::WRITEABLE); if (config.cacheHolePunchLayer) { + SFTRACE_NAME("cacheHolePunchLayer"); drawHolePunchLayer(renderengine, display, dstTexture); } if (config.cacheSolidLayers) { + SFTRACE_NAME("cacheSolidLayers"); drawSolidLayers(renderengine, display, dstTexture); drawSolidLayers(renderengine, p3Display, dstTexture); } if (config.cacheSolidDimmedLayers) { + SFTRACE_NAME("cacheSolidDimmedLayers"); drawSolidDimmedLayers(renderengine, display, dstTexture); } if (config.cacheShadowLayers) { + SFTRACE_NAME("cacheShadowLayers"); drawShadowLayers(renderengine, display, srcTexture); drawShadowLayers(renderengine, p3Display, srcTexture); } if (renderengine->supportsBackgroundBlur()) { + SFTRACE_NAME("supportsBackgroundBlur"); drawBlurLayers(renderengine, display, dstTexture); } @@ -776,32 +786,37 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine, PrimeCacheConfig co for (auto texture : textures) { if (config.cacheImageLayers) { + SFTRACE_NAME("cacheImageLayers"); drawImageLayers(renderengine, display, dstTexture, texture); } if (config.cacheImageDimmedLayers) { + SFTRACE_NAME("cacheImageDimmedLayers"); drawImageDimmedLayers(renderengine, display, dstTexture, texture); drawImageDimmedLayers(renderengine, p3Display, dstTexture, texture); drawImageDimmedLayers(renderengine, bt2020Display, dstTexture, texture); } if (config.cacheClippedLayers) { + SFTRACE_NAME("cacheClippedLayers"); // Draw layers for b/185569240. drawClippedLayers(renderengine, display, dstTexture, texture); } - if (com::android::graphics::libgui::flags::edge_extension_shader() && - config.cacheEdgeExtension) { + if (config.cacheEdgeExtension) { + SFTRACE_NAME("cacheEdgeExtension"); drawEdgeExtensionLayers(renderengine, display, dstTexture, texture); drawEdgeExtensionLayers(renderengine, p3Display, dstTexture, texture); } } if (config.cachePIPImageLayers) { + SFTRACE_NAME("cachePIPImageLayers"); drawPIPImageLayer(renderengine, display, dstTexture, externalTexture); } if (config.cacheTransparentImageDimmedLayers) { + SFTRACE_NAME("cacheTransparentImageDimmedLayers"); drawTransparentImageDimmedLayers(renderengine, bt2020Display, dstTexture, externalTexture); drawTransparentImageDimmedLayers(renderengine, display, dstTexture, externalTexture); @@ -811,10 +826,12 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine, PrimeCacheConfig co } if (config.cacheClippedDimmedImageLayers) { + SFTRACE_NAME("cacheClippedDimmedImageLayers"); drawClippedDimmedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture); } if (config.cacheUltraHDR) { + SFTRACE_NAME("cacheUltraHDR"); drawBT2020ClippedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture); drawBT2020ImageLayers(renderengine, bt2020Display, dstTexture, externalTexture); @@ -833,7 +850,10 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine, PrimeCacheConfig co }; auto layers = std::vector<LayerSettings>{layer}; // call get() to make it synchronous - renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()).get(); + { + SFTRACE_NAME("finalLayer"); + renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()).get(); + } const nsecs_t timeAfter = systemTime(); const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6; diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp index 14d08eea74..25afc7b465 100644 --- a/libs/renderengine/skia/SkiaRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaRenderEngine.cpp @@ -347,6 +347,7 @@ void SkiaRenderEngine::useProtectedContext(bool useProtectedContext) { if (useProtectedContextImpl( useProtectedContext ? GrProtected::kYes : GrProtected::kNo)) { mInProtectedContext = useProtectedContext; + SFTRACE_INT("RE inProtectedContext", mInProtectedContext); // given that we are sharing the same thread between two contexts we need to // make sure that the thread state is reset when switching between the two. if (getActiveContext()) { @@ -838,8 +839,7 @@ void SkiaRenderEngine::drawLayersInternal( LOG_ALWAYS_FATAL_IF(activeSurface == dstSurface); LOG_ALWAYS_FATAL_IF(canvas == dstCanvas); - // save a snapshot of the activeSurface to use as input to the blur shaders - blurInput = activeSurface->makeImageSnapshot(); + blurInput = activeSurface->makeTemporaryImage(); // blit the offscreen framebuffer into the destination AHB. This ensures that // even if the blurred image does not cover the screen (for example, during @@ -853,12 +853,9 @@ void SkiaRenderEngine::drawLayersInternal( dstCanvas->drawAnnotation(SkRect::Make(dstCanvas->imageInfo().dimensions()), String8::format("SurfaceID|%" PRId64, id).c_str(), nullptr); - dstCanvas->drawImage(blurInput, 0, 0, SkSamplingOptions(), &paint); - } else { - activeSurface->draw(dstCanvas, 0, 0, SkSamplingOptions(), &paint); } + dstCanvas->drawImage(blurInput, 0, 0, SkSamplingOptions(), &paint); } - // assign dstCanvas to canvas and ensure that the canvas state is up to date canvas = dstCanvas; surfaceAutoSaveRestore.replace(canvas); @@ -891,12 +888,6 @@ void SkiaRenderEngine::drawLayersInternal( if (mBlurFilter && layerHasBlur(layer, ctModifiesAlpha)) { std::unordered_map<uint32_t, sk_sp<SkImage>> cachedBlurs; - // if multiple layers have blur, then we need to take a snapshot now because - // only the lowest layer will have blurImage populated earlier - if (!blurInput) { - blurInput = activeSurface->makeImageSnapshot(); - } - // rect to be blurred in the coordinate space of blurInput SkRect blurRect = canvas->getTotalMatrix().mapRect(bounds.rect()); @@ -920,6 +911,29 @@ void SkiaRenderEngine::drawLayersInternal( // TODO(b/182216890): Filter out empty layers earlier if (blurRect.width() > 0 && blurRect.height() > 0) { + // if multiple layers have blur, then we need to take a snapshot now because + // only the lowest layer will have blurImage populated earlier + if (!blurInput) { + bool requiresCrossFadeWithBlurInput = false; + if (layer.backgroundBlurRadius > 0 && + layer.backgroundBlurRadius < mBlurFilter->getMaxCrossFadeRadius()) { + requiresCrossFadeWithBlurInput = true; + } + for (auto region : layer.blurRegions) { + if (region.blurRadius < mBlurFilter->getMaxCrossFadeRadius()) { + requiresCrossFadeWithBlurInput = true; + } + } + if (requiresCrossFadeWithBlurInput) { + // If we require cross fading with the blur input, we need to make sure we + // make a copy of the surface to the image since we will be writing to the + // surface while sampling the blurInput. + blurInput = activeSurface->makeImageSnapshot(); + } else { + blurInput = activeSurface->makeTemporaryImage(); + } + } + if (layer.backgroundBlurRadius > 0) { SFTRACE_NAME("BackgroundBlur"); auto blurredImage = mBlurFilter->generate(context, layer.backgroundBlurRadius, diff --git a/libs/renderengine/skia/compat/GraphiteGpuContext.cpp b/libs/renderengine/skia/compat/GraphiteGpuContext.cpp index 69f583226b..7a72d09804 100644 --- a/libs/renderengine/skia/compat/GraphiteGpuContext.cpp +++ b/libs/renderengine/skia/compat/GraphiteGpuContext.cpp @@ -110,8 +110,40 @@ bool GraphiteGpuContext::isAbandonedOrDeviceLost() { return mContext->isDeviceLost(); } +void GraphiteGpuContext::setResourceCacheLimit(size_t maxResourceBytes) { + // Graphite has a separate budget for its Context and its Recorder. For now the majority of + // memory that Graphite will allocate will be on the Recorder and minimal amount on the Context. + // The main allocations on the Context are MSAA buffers (not often, if ever used in + // RenderEngine) and stencil buffers. However, both of these should be "memoryless" in Vulkan on + // tiled GPUs, so they don't actually use GPU memory. However, in Vulkan there are scenarios + // where Vulkan could end up using real memory for them. Skia will regularly query the device to + // get the real memory usage and update the budgeted appropriately. Though for all real usage + // patterns we don't expect to ever trigger the device to allocate real memory. + // + // Therefore, we set the full maxResourceBytes budget on the Recorder. However, in the rare + // chance that the devcies does allocate real memory we don't want to immediately kill device + // performance by constantly trashing allocations on the Context. Thus we set the Context's + // budget to be 50% of the total budget to make sure we allow the MSAA or Stencil buffers to be + // allocated in Skia and not immediately discarded. But even with this extra 50% budget, as + // described above, this shouldn't result in actual GPU memory usage. + // + // TODO: We will need to revise this strategy for GLES which does not have the same memoryless + // textures. + // TODO: Work in Graphite has started to move a lot more of its scratch resources to be owned + // by the Context and not on Recorders. This will mean most memory is actually owned by the + // Context and thus the budgeting here will need to be updated. + mContext->setMaxBudgetedBytes(maxResourceBytes / 2); + mRecorder->setMaxBudgetedBytes(maxResourceBytes); +} + +void GraphiteGpuContext::purgeUnlockedScratchResources() { + mContext->freeGpuResources(); + mRecorder->freeGpuResources(); +} + void GraphiteGpuContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { mContext->dumpMemoryStatistics(traceMemoryDump); + mRecorder->dumpMemoryStatistics(traceMemoryDump); } } // namespace android::renderengine::skia diff --git a/libs/renderengine/skia/compat/GraphiteGpuContext.h b/libs/renderengine/skia/compat/GraphiteGpuContext.h index 413817ffff..57da796af5 100644 --- a/libs/renderengine/skia/compat/GraphiteGpuContext.h +++ b/libs/renderengine/skia/compat/GraphiteGpuContext.h @@ -39,16 +39,10 @@ public: size_t getMaxRenderTargetSize() const override; size_t getMaxTextureSize() const override; bool isAbandonedOrDeviceLost() override; - // No-op (large resources like textures, surfaces, images, etc. created by clients don't count - // towards Graphite's internal caching budgets, so adjusting its limits based on display change - // events should be unnecessary. Additionally, Graphite doesn't expose many cache tweaking - // functions yet, as its design may evolve.) - void setResourceCacheLimit(size_t maxResourceBytes) override{}; - // TODO: b/293371537 - Triple-check and validate that no cleanup is necessary when switching - // contexts. - // No-op (unnecessary during context switch for Graphite's client-budgeted memory model). - void purgeUnlockedScratchResources() override{}; + void setResourceCacheLimit(size_t maxResourceBytes) override; + void purgeUnlockedScratchResources() override; + // No-op (only applicable to GL). void resetContextIfApplicable() override{}; diff --git a/libs/renderengine/skia/debug/CaptureTimer.cpp b/libs/renderengine/skia/debug/CaptureTimer.cpp index 11bcdb8996..1c1ee0abb3 100644 --- a/libs/renderengine/skia/debug/CaptureTimer.cpp +++ b/libs/renderengine/skia/debug/CaptureTimer.cpp @@ -30,7 +30,7 @@ namespace skia { void CaptureTimer::setTimeout(TimeoutCallback function, std::chrono::milliseconds delay) { this->clear = false; - CommonPool::post([=]() { + CommonPool::post([=,this]() { if (this->clear) return; std::this_thread::sleep_for(delay); if (this->clear) return; diff --git a/libs/renderengine/skia/filters/BlurFilter.cpp b/libs/renderengine/skia/filters/BlurFilter.cpp index cd1bd71807..8edf98eb89 100644 --- a/libs/renderengine/skia/filters/BlurFilter.cpp +++ b/libs/renderengine/skia/filters/BlurFilter.cpp @@ -90,6 +90,8 @@ void BlurFilter::drawBlurRegion(SkCanvas* canvas, const SkRRect& effectRegion, linearSampling, &blurMatrix); if (blurRadius < mMaxCrossFadeRadius) { + LOG_ALWAYS_FATAL_IF(!input); + // For sampling Skia's API expects the inverse of what logically seems appropriate. In this // case you might expect the matrix to simply be the canvas matrix. SkMatrix inputMatrix; diff --git a/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.cpp b/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.cpp index 4164c4b4c9..f007427f1c 100644 --- a/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.cpp +++ b/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.cpp @@ -58,9 +58,6 @@ static const SkString edgeShader = SkString(R"( )"); EdgeExtensionShaderFactory::EdgeExtensionShaderFactory() { - if (!com::android::graphics::libgui::flags::edge_extension_shader()) { - return; - } mResult = std::make_unique<SkRuntimeEffect::Result>(SkRuntimeEffect::MakeForShader(edgeShader)); LOG_ALWAYS_FATAL_IF(!mResult->errorText.isEmpty(), "EdgeExtensionShaderFactory compilation " diff --git a/libs/renderengine/skia/filters/GaussianBlurFilter.cpp b/libs/renderengine/skia/filters/GaussianBlurFilter.cpp index 8c52c571a9..b03ebe3353 100644 --- a/libs/renderengine/skia/filters/GaussianBlurFilter.cpp +++ b/libs/renderengine/skia/filters/GaussianBlurFilter.cpp @@ -64,7 +64,7 @@ sk_sp<SkImage> GaussianBlurFilter::generate(SkiaGpuContext* context, const uint3 SkSamplingOptions{SkFilterMode::kLinear, SkMipmapMode::kNone}, &paint, SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint); - return surface->makeImageSnapshot(); + return surface->makeTemporaryImage(); } } // namespace skia diff --git a/libs/renderengine/skia/filters/KawaseBlurDualFilter.cpp b/libs/renderengine/skia/filters/KawaseBlurDualFilter.cpp index 750e08fa55..ff96b08283 100644 --- a/libs/renderengine/skia/filters/KawaseBlurDualFilter.cpp +++ b/libs/renderengine/skia/filters/KawaseBlurDualFilter.cpp @@ -39,12 +39,36 @@ namespace renderengine { namespace skia { KawaseBlurDualFilter::KawaseBlurDualFilter() : BlurFilter() { - // A shader to sample each vertex of a unit regular heptagon - // plus the original fragment coordinate. - SkString blurString(R"( + // A shader to sample each vertex of a square, plus the original fragment coordinate, + // using a total of 5 samples. + SkString lowSampleBlurString(R"( uniform shader child; uniform float in_blurOffset; uniform float in_crossFade; + uniform float in_weightedCrossFade; + + const float2 STEP_0 = float2( 0.707106781, 0.707106781); + const float2 STEP_1 = float2( 0.707106781, -0.707106781); + const float2 STEP_2 = float2(-0.707106781, -0.707106781); + const float2 STEP_3 = float2(-0.707106781, 0.707106781); + + half4 main(float2 xy) { + half3 c = child.eval(xy).rgb; + + c += child.eval(xy + STEP_0 * in_blurOffset).rgb; + c += child.eval(xy + STEP_1 * in_blurOffset).rgb; + c += child.eval(xy + STEP_2 * in_blurOffset).rgb; + c += child.eval(xy + STEP_3 * in_blurOffset).rgb; + + return half4(c * in_weightedCrossFade, in_crossFade); + } + )"); + + // A shader to sample each vertex of a unit regular heptagon, plus the original fragment + // coordinate, using a total of 8 samples. + SkString highSampleBlurString(R"( + uniform shader child; + uniform float in_blurOffset; const float2 STEP_0 = float2( 1.0, 0.0); const float2 STEP_1 = float2( 0.623489802, 0.781831482); @@ -65,39 +89,46 @@ KawaseBlurDualFilter::KawaseBlurDualFilter() : BlurFilter() { c += child.eval(xy + STEP_5 * in_blurOffset).rgb; c += child.eval(xy + STEP_6 * in_blurOffset).rgb; - return half4(c * 0.125 * in_crossFade, in_crossFade); + return half4(c * 0.125, 1.0); } )"); - auto [blurEffect, error] = SkRuntimeEffect::MakeForShader(blurString); - LOG_ALWAYS_FATAL_IF(!blurEffect, "RuntimeShader error: %s", error.c_str()); - mBlurEffect = std::move(blurEffect); + auto [lowSampleBlurEffect, error] = SkRuntimeEffect::MakeForShader(lowSampleBlurString); + auto [highSampleBlurEffect, error2] = SkRuntimeEffect::MakeForShader(highSampleBlurString); + LOG_ALWAYS_FATAL_IF(!lowSampleBlurEffect, "RuntimeShader error: %s", error.c_str()); + LOG_ALWAYS_FATAL_IF(!highSampleBlurEffect, "RuntimeShader error: %s", error2.c_str()); + mLowSampleBlurEffect = std::move(lowSampleBlurEffect); + mHighSampleBlurEffect = std::move(highSampleBlurEffect); } void KawaseBlurDualFilter::blurInto(const sk_sp<SkSurface>& drawSurface, const sk_sp<SkImage>& readImage, const float radius, - const float alpha) const { + const float alpha, + const sk_sp<SkRuntimeEffect>& blurEffect) const { const float scale = static_cast<float>(drawSurface->width()) / readImage->width(); SkMatrix blurMatrix = SkMatrix::Scale(scale, scale); blurInto(drawSurface, readImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone), blurMatrix), - readImage->width() / static_cast<float>(drawSurface->width()), radius, alpha); + radius, alpha, blurEffect); } void KawaseBlurDualFilter::blurInto(const sk_sp<SkSurface>& drawSurface, sk_sp<SkShader> input, - const float inverseScale, const float radius, - const float alpha) const { + const float radius, const float alpha, + const sk_sp<SkRuntimeEffect>& blurEffect) const { SkPaint paint; if (radius == 0) { paint.setShader(std::move(input)); paint.setAlphaf(alpha); } else { - SkRuntimeShaderBuilder blurBuilder(mBlurEffect); + SkRuntimeShaderBuilder blurBuilder(blurEffect); blurBuilder.child("child") = std::move(input); + if (blurEffect == mLowSampleBlurEffect) { + blurBuilder.uniform("in_crossFade") = alpha; + blurBuilder.uniform("in_weightedCrossFade") = alpha * 0.2f; + } blurBuilder.uniform("in_blurOffset") = radius; - blurBuilder.uniform("in_crossFade") = alpha; paint.setShader(blurBuilder.makeShader(nullptr)); } paint.setBlendMode(alpha == 1.0f ? SkBlendMode::kSrc : SkBlendMode::kSrcOver); @@ -118,9 +149,12 @@ sk_sp<SkImage> KawaseBlurDualFilter::generate(SkiaGpuContext* context, const uin const int filterPasses = std::min(kMaxSurfaces - 1, static_cast<int>(ceil(filterDepth))); auto makeSurface = [&](float scale) -> sk_sp<SkSurface> { - const auto newW = static_cast<float>(blurRect.width() / scale); - const auto newH = static_cast<float>(blurRect.height() / scale); - return context->createRenderTarget(input->imageInfo().makeWH(newW, newH)); + const auto newW = ceil(static_cast<float>(blurRect.width() / scale)); + const auto newH = ceil(static_cast<float>(blurRect.height() / scale)); + sk_sp<SkSurface> surface = + context->createRenderTarget(input->imageInfo().makeWH(newW, newH)); + LOG_ALWAYS_FATAL_IF(!surface, "%s: Failed to create surface for blurring!", __func__); + return surface; }; // Render into surfaces downscaled by 1x, 2x, and 4x from the initial downscale. @@ -160,18 +194,21 @@ sk_sp<SkImage> KawaseBlurDualFilter::generate(SkiaGpuContext* context, const uin input->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone), blurMatrix); - blurInto(surfaces[0], std::move(sourceShader), kInputScale, kWeights[0] * step, 1.0f); + blurInto(surfaces[0], std::move(sourceShader), kWeights[0] * step, 1.0f, + mLowSampleBlurEffect); } // Next the remaining downscale blur passes. for (int i = 0; i < filterPasses; i++) { - blurInto(surfaces[i + 1], surfaces[i]->makeImageSnapshot(), kWeights[1 + i] * step, 1.0f); + // Blur with the higher sample effect into the smaller buffers, for better visual quality. + blurInto(surfaces[i + 1], surfaces[i]->makeTemporaryImage(), kWeights[1 + i] * step, 1.0f, + i == 0 ? mLowSampleBlurEffect : mHighSampleBlurEffect); } // Finally blur+upscale back to our original size. for (int i = filterPasses - 1; i >= 0; i--) { - blurInto(surfaces[i], surfaces[i + 1]->makeImageSnapshot(), kWeights[4 - i] * step, - std::min(1.0f, filterDepth - i)); + blurInto(surfaces[i], surfaces[i + 1]->makeTemporaryImage(), kWeights[4 - i] * step, + std::min(1.0f, filterDepth - i), mLowSampleBlurEffect); } - return surfaces[0]->makeImageSnapshot(); + return surfaces[0]->makeTemporaryImage(); } } // namespace skia diff --git a/libs/renderengine/skia/filters/KawaseBlurDualFilter.h b/libs/renderengine/skia/filters/KawaseBlurDualFilter.h index 6f4adbf34c..5efda35376 100644 --- a/libs/renderengine/skia/filters/KawaseBlurDualFilter.h +++ b/libs/renderengine/skia/filters/KawaseBlurDualFilter.h @@ -41,13 +41,14 @@ public: const sk_sp<SkImage> blurInput, const SkRect& blurRect) const override; private: - sk_sp<SkRuntimeEffect> mBlurEffect; + sk_sp<SkRuntimeEffect> mLowSampleBlurEffect; + sk_sp<SkRuntimeEffect> mHighSampleBlurEffect; void blurInto(const sk_sp<SkSurface>& drawSurface, const sk_sp<SkImage>& readImage, - const float radius, const float alpha) const; + const float radius, const float alpha, const sk_sp<SkRuntimeEffect>&) const; void blurInto(const sk_sp<SkSurface>& drawSurface, const sk_sp<SkShader> input, - const float inverseScale, const float radius, const float alpha) const; + const float radius, const float alpha, const sk_sp<SkRuntimeEffect>&) const; }; } // namespace skia diff --git a/libs/renderengine/skia/filters/KawaseBlurFilter.cpp b/libs/renderengine/skia/filters/KawaseBlurFilter.cpp index defaf6e476..f71a63d591 100644 --- a/libs/renderengine/skia/filters/KawaseBlurFilter.cpp +++ b/libs/renderengine/skia/filters/KawaseBlurFilter.cpp @@ -70,7 +70,7 @@ static sk_sp<SkImage> makeImage(SkSurface* surface, SkRuntimeShaderBuilder* buil paint.setShader(std::move(shader)); paint.setBlendMode(SkBlendMode::kSrc); surface->getCanvas()->drawPaint(paint); - return surface->makeImageSnapshot(); + return surface->makeTemporaryImage(); } sk_sp<SkImage> KawaseBlurFilter::generate(SkiaGpuContext* context, const uint32_t blurRadius, diff --git a/libs/renderengine/skia/filters/LutShader.cpp b/libs/renderengine/skia/filters/LutShader.cpp index 10218bb822..f262158f2c 100644 --- a/libs/renderengine/skia/filters/LutShader.cpp +++ b/libs/renderengine/skia/filters/LutShader.cpp @@ -182,8 +182,8 @@ sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input, * (R1, G1, B1, 0) * ... */ - SkImageInfo info = SkImageInfo::Make(length /* the number of rgba */ * 4, 1, - kRGBA_F16_SkColorType, kPremul_SkAlphaType); + SkImageInfo info = SkImageInfo::Make(length /* the number of rgba */, 1, kRGBA_F16_SkColorType, + kPremul_SkAlphaType); SkBitmap bitmap; bitmap.allocPixels(info); if (!bitmap.installPixels(info, buffer.data(), info.minRowBytes())) { diff --git a/libs/renderengine/skia/filters/MouriMap.cpp b/libs/renderengine/skia/filters/MouriMap.cpp index aa12cef615..5dc36e6358 100644 --- a/libs/renderengine/skia/filters/MouriMap.cpp +++ b/libs/renderengine/skia/filters/MouriMap.cpp @@ -104,7 +104,7 @@ sk_sp<SkImage> makeImage(SkSurface* surface, const SkRuntimeShaderBuilder& build paint.setShader(std::move(shader)); paint.setBlendMode(SkBlendMode::kSrc); surface->getCanvas()->drawPaint(paint); - return surface->makeImageSnapshot(); + return surface->makeTemporaryImage(); } } // namespace diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp index ea5605d4bd..67f4aa10f8 100644 --- a/libs/renderengine/threaded/RenderEngineThreaded.cpp +++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp @@ -23,6 +23,7 @@ #include <future> #include <android-base/stringprintf.h> +#include <common/FlagManager.h> #include <common/trace.h> #include <private/gui/SyncFeatures.h> #include <processgroup/processgroup.h> @@ -60,7 +61,7 @@ status_t RenderEngineThreaded::setSchedFifo(bool enabled) { struct sched_param param = {0}; int sched_policy; - if (enabled) { + if (enabled && !FlagManager::getInstance().disable_sched_fifo_re()) { sched_policy = SCHED_FIFO; param.sched_priority = kFifoPriority; } else { diff --git a/libs/sensor/OWNERS b/libs/sensor/OWNERS index 7347ac74e6..4929b3fc92 100644 --- a/libs/sensor/OWNERS +++ b/libs/sensor/OWNERS @@ -1 +1 @@ -bduddie@google.com +include platform/frameworks/native:/services/sensorservice/OWNERS
\ No newline at end of file diff --git a/libs/shaders/OWNERS b/libs/shaders/OWNERS index 6d91da3bd2..6977a49cc9 100644 --- a/libs/shaders/OWNERS +++ b/libs/shaders/OWNERS @@ -1,4 +1,3 @@ alecmouri@google.com jreck@google.com sallyqi@google.com -scroggo@google.com
\ No newline at end of file diff --git a/libs/tonemap/OWNERS b/libs/tonemap/OWNERS index 6d91da3bd2..6977a49cc9 100644 --- a/libs/tonemap/OWNERS +++ b/libs/tonemap/OWNERS @@ -1,4 +1,3 @@ alecmouri@google.com jreck@google.com sallyqi@google.com -scroggo@google.com
\ No newline at end of file diff --git a/libs/tracing_perfetto/include/tracing_sdk.h b/libs/tracing_perfetto/include/tracing_sdk.h index 4a6e849567..271d7c8563 100644 --- a/libs/tracing_perfetto/include/tracing_sdk.h +++ b/libs/tracing_perfetto/include/tracing_sdk.h @@ -27,6 +27,10 @@ #include "perfetto/public/te_macros.h" #include "perfetto/public/track_event.h" +#include "perfetto/public/abi/pb_decoder_abi.h" +#include "perfetto/public/pb_utils.h" +#include "perfetto/public/tracing_session.h" + /** * The objects declared here are intended to be managed by Java. * This means the Java Garbage Collector is responsible for freeing the @@ -288,13 +292,8 @@ class DebugArg { arg_ = std::move(arg); } - ~DebugArg() { - free_string_value(); - } - void set_value(T value) { if constexpr (std::is_same_v<T, const char*>) { - free_string_value(); arg_.value = value; } else if constexpr (std::is_same_v<T, int64_t>) { arg_.value = value; @@ -317,16 +316,6 @@ class DebugArg { DISALLOW_COPY_AND_ASSIGN(DebugArg); TypeMap::type arg_; const std::string name_; - - constexpr void free_string_value() { - if constexpr (std::is_same_v<typename TypeMap::type, - PerfettoTeHlExtraDebugArgString>) { - if (arg_.value) { - free((void*)arg_.value); - arg_.value = nullptr; - } - } - } }; template <typename T> @@ -371,10 +360,6 @@ class ProtoField { arg_ = std::move(arg); } - ~ProtoField() { - free_string_value(); - } - void set_value(uint32_t id, T value) { if constexpr (std::is_same_v<T, int64_t>) { arg_.header.id = id; @@ -383,7 +368,6 @@ class ProtoField { arg_.header.id = id; arg_.value = value; } else if constexpr (std::is_same_v<T, const char*>) { - free_string_value(); arg_.header.id = id; arg_.str = value; } @@ -400,16 +384,6 @@ class ProtoField { private: DISALLOW_COPY_AND_ASSIGN(ProtoField); TypeMap::type arg_; - - constexpr void free_string_value() { - if constexpr (std::is_same_v<typename TypeMap::type, - PerfettoTeHlProtoFieldCstr>) { - if (arg_.str) { - free((void*)arg_.str); - arg_.str = nullptr; - } - } - } }; class ProtoFieldNested { @@ -452,6 +426,22 @@ class Proto { std::vector<PerfettoTeHlProtoField*> fields_; }; +class Session { + public: + Session(bool is_backend_in_process, void* buf, size_t len); + ~Session(); + Session(const Session&) = delete; + Session& operator=(const Session&) = delete; + + bool FlushBlocking(uint32_t timeout_ms); + void StopBlocking(); + std::vector<uint8_t> ReadBlocking(); + + static void delete_session(Session* session); + + struct PerfettoTracingSessionImpl* session_ = nullptr; +}; + /** * @brief Activates a trigger. * @param name The name of the trigger. diff --git a/libs/tracing_perfetto/tests/Android.bp b/libs/tracing_perfetto/tests/Android.bp index 0dab517b7f..79fb704906 100644 --- a/libs/tracing_perfetto/tests/Android.bp +++ b/libs/tracing_perfetto/tests/Android.bp @@ -21,44 +21,12 @@ package { default_applicable_licenses: ["frameworks_native_license"], } -cc_library_static { - name: "libtracing_perfetto_test_utils", - export_include_dirs: [ - "include", - ], - static_libs: [ - "libflagtest", - "libgmock", - "perfetto_trace_protos", - ], - cflags: [ - "-Wall", - "-Werror", - "-Wno-enum-compare", - "-Wno-unused-function", - ], - - srcs: [ - "utils.cpp", - ], - - shared_libs: [ - "libperfetto_c", - "liblog", - "libprotobuf-cpp-lite", - ], - export_shared_lib_headers: [ - "libperfetto_c", - ], -} - cc_test { name: "libtracing_perfetto_tests", static_libs: [ "libflagtest", "libgmock", "perfetto_trace_protos", - "libtracing_perfetto_test_utils", ], cflags: [ "-Wall", @@ -68,12 +36,15 @@ cc_test { "android.os.flags-aconfig-cc-host", "libbase", "libperfetto_c", - "liblog", "libprotobuf-cpp-lite", "libtracing_perfetto", ], srcs: [ "tracing_perfetto_test.cpp", + "utils.cpp", + ], + local_include_dirs: [ + "include", ], test_suites: ["device-tests"], } diff --git a/libs/tracing_perfetto/tracing_perfetto_internal.cpp b/libs/tracing_perfetto/tracing_perfetto_internal.cpp index f92f6df990..447873290c 100644 --- a/libs/tracing_perfetto/tracing_perfetto_internal.cpp +++ b/libs/tracing_perfetto/tracing_perfetto_internal.cpp @@ -14,15 +14,16 @@ * limitations under the License. */ +// Should match the definitions in: frameworks/native/cmds/atrace/atrace.cpp #define FRAMEWORK_CATEGORIES(C) \ C(always, "always", "Always category") \ - C(graphics, "graphics", "Graphics category") \ + C(graphics, "gfx", "Graphics category") \ C(input, "input", "Input category") \ C(view, "view", "View category") \ C(webview, "webview", "WebView category") \ C(windowmanager, "wm", "WindowManager category") \ C(activitymanager, "am", "ActivityManager category") \ - C(syncmanager, "syncmanager", "SyncManager category") \ + C(syncmanager, "sm", "SyncManager category") \ C(audio, "audio", "Audio category") \ C(video, "video", "Video category") \ C(camera, "camera", "Camera category") \ @@ -33,7 +34,7 @@ C(rs, "rs", "RS category") \ C(bionic, "bionic", "Bionic category") \ C(power, "power", "Power category") \ - C(packagemanager, "packagemanager", "PackageManager category") \ + C(packagemanager, "pm", "PackageManager category") \ C(systemserver, "ss", "System Server category") \ C(database, "database", "Database category") \ C(network, "network", "Network category") \ diff --git a/libs/tracing_perfetto/tracing_perfetto_internal.h b/libs/tracing_perfetto/tracing_perfetto_internal.h index 3e1ac2a112..0e3fb07efd 100644 --- a/libs/tracing_perfetto/tracing_perfetto_internal.h +++ b/libs/tracing_perfetto/tracing_perfetto_internal.h @@ -25,8 +25,6 @@ namespace tracing_perfetto { namespace internal { -bool isPerfettoRegistered(); - struct PerfettoTeCategory* toPerfettoCategory(uint64_t category); void registerWithPerfetto(bool test = false); diff --git a/libs/tracing_perfetto/tracing_sdk.cpp b/libs/tracing_perfetto/tracing_sdk.cpp index 02e8d10aa4..70b8be981b 100644 --- a/libs/tracing_perfetto/tracing_sdk.cpp +++ b/libs/tracing_perfetto/tracing_sdk.cpp @@ -38,7 +38,7 @@ void trace_event(int type, const PerfettoTeCategory* perfettoTeCategory, PerfettoTeHlEmitImpl(perfettoTeCategory->impl, type, type == PERFETTO_TE_TYPE_COUNTER ? nullptr : name, extra->get()); - extra->pop_extra(); + extra->clear_extras(); } } @@ -254,6 +254,47 @@ const PerfettoTeHlProtoFieldNested* ProtoFieldNested::get() const { return &field_; } +Session::Session(bool is_backend_in_process, void* buf, size_t len) { + session_ = PerfettoTracingSessionCreate(is_backend_in_process + ? PERFETTO_BACKEND_IN_PROCESS + : PERFETTO_BACKEND_SYSTEM); + + PerfettoTracingSessionSetup(session_, buf, len); + + PerfettoTracingSessionStartBlocking(session_); +} + +Session::~Session() { + PerfettoTracingSessionStopBlocking(session_); + PerfettoTracingSessionDestroy(session_); +} + +bool Session::FlushBlocking(uint32_t timeout_ms) { + return PerfettoTracingSessionFlushBlocking(session_, timeout_ms); +} + +void Session::StopBlocking() { + PerfettoTracingSessionStopBlocking(session_); +} + +std::vector<uint8_t> Session::ReadBlocking() { + std::vector<uint8_t> data; + PerfettoTracingSessionReadTraceBlocking( + session_, + [](struct PerfettoTracingSessionImpl*, const void* trace_data, + size_t size, bool, void* user_arg) { + auto& dst = *static_cast<std::vector<uint8_t>*>(user_arg); + auto* src = static_cast<const uint8_t*>(trace_data); + dst.insert(dst.end(), src, src + size); + }, + &data); + return data; +} + +void Session::delete_session(Session* ptr) { + delete ptr; +} + void activate_trigger(const char* name, uint32_t ttl_ms) { const char* names[] = {name, nullptr}; PerfettoProducerActivateTriggers(names, ttl_ms); diff --git a/libs/ui/DisplayIdentification.cpp b/libs/ui/DisplayIdentification.cpp index c9f0761a01..78e84fc4dc 100644 --- a/libs/ui/DisplayIdentification.cpp +++ b/libs/ui/DisplayIdentification.cpp @@ -26,6 +26,7 @@ #include <string> #include <string_view> +#include <ftl/concat.h> #include <ftl/hash.h> #include <log/log.h> #include <ui/DisplayIdentification.h> @@ -392,10 +393,6 @@ std::optional<PnpId> getPnpId(uint16_t manufacturerId) { return a && b && c ? std::make_optional(PnpId{a, b, c}) : std::nullopt; } -std::optional<PnpId> getPnpId(PhysicalDisplayId displayId) { - return getPnpId(displayId.getManufacturerId()); -} - std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData( uint8_t port, const DisplayIdentificationData& data) { if (data.empty()) { @@ -427,4 +424,27 @@ PhysicalDisplayId getVirtualDisplayId(uint32_t id) { return PhysicalDisplayId::fromEdid(0, kVirtualEdidManufacturerId, id); } +PhysicalDisplayId generateEdidDisplayId(const Edid& edid) { + const ftl::Concat displayDetailsString{edid.manufacturerId, + edid.productId, + ftl::truncated<13>(edid.displayName), + edid.manufactureWeek, + edid.manufactureOrModelYear, + edid.physicalSizeInCm.getWidth(), + edid.physicalSizeInCm.getHeight()}; + + // String has to be cropped to 64 characters (at most) for ftl::stable_hash. + // This is fine as the accuracy or completeness of the above fields is not + // critical for a ID fabrication. + const std::optional<uint64_t> hashedDisplayDetailsOpt = + ftl::stable_hash(std::string_view(displayDetailsString.c_str(), 64)); + + // Combine the hashes via bit-shifted XORs. + const uint64_t id = (hashedDisplayDetailsOpt.value_or(0) << 17) ^ + (edid.hashedBlockZeroSerialNumberOpt.value_or(0) >> 11) ^ + (edid.hashedDescriptorBlockSerialNumberOpt.value_or(0) << 23); + + return PhysicalDisplayId::fromValue(id); +} + } // namespace android diff --git a/libs/ui/OWNERS b/libs/ui/OWNERS index a0b5fe7119..2a85a4b493 100644 --- a/libs/ui/OWNERS +++ b/libs/ui/OWNERS @@ -2,6 +2,5 @@ adyabr@google.com alecmouri@google.com chrisforbes@google.com jreck@google.com -lpy@google.com mathias@google.com romainguy@google.com diff --git a/libs/ui/include/ui/DisplayId.h b/libs/ui/include/ui/DisplayId.h index 8a14db8ffa..1e1c77b9fc 100644 --- a/libs/ui/include/ui/DisplayId.h +++ b/libs/ui/include/ui/DisplayId.h @@ -20,7 +20,7 @@ #include <ostream> #include <string> -#include <ftl/hash.h> +#include <ftl/match.h> #include <ftl/optional.h> namespace android { @@ -31,31 +31,15 @@ struct DisplayId { // Flag indicating that the display is virtual. static constexpr uint64_t FLAG_VIRTUAL = 1ULL << 63; - // Flag indicating that the ID is stable across reboots. - static constexpr uint64_t FLAG_STABLE = 1ULL << 62; - - // TODO(b/162612135) Remove default constructor + // TODO: b/162612135 - Remove default constructor. DisplayId() = default; constexpr DisplayId(const DisplayId&) = default; DisplayId& operator=(const DisplayId&) = default; - constexpr bool isVirtual() const { return value & FLAG_VIRTUAL; } - constexpr bool isStable() const { return value & FLAG_STABLE; } + static constexpr DisplayId fromValue(uint64_t value) { return DisplayId(value); } uint64_t value; - // For deserialization. - static constexpr std::optional<DisplayId> fromValue(uint64_t); - - // As above, but also upcast to Id. - template <typename Id> - static constexpr std::optional<Id> fromValue(uint64_t value) { - if (const auto id = Id::tryCast(DisplayId(value))) { - return id; - } - return {}; - } - protected: explicit constexpr DisplayId(uint64_t id) : value(id) {} }; @@ -79,14 +63,10 @@ inline std::ostream& operator<<(std::ostream& stream, DisplayId displayId) { // DisplayId of a physical display, such as the internal display or externally connected display. struct PhysicalDisplayId : DisplayId { - static constexpr ftl::Optional<PhysicalDisplayId> tryCast(DisplayId id) { - if (id.isVirtual()) { - return std::nullopt; - } - return PhysicalDisplayId(id); - } + // TODO: b/162612135 - Remove default constructor. + PhysicalDisplayId() = default; - // Returns a stable ID based on EDID information. + // Returns a stable ID based on EDID and port information. static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId, uint32_t modelHash) { return PhysicalDisplayId(FLAG_STABLE, port, manufacturerId, modelHash); @@ -99,13 +79,16 @@ struct PhysicalDisplayId : DisplayId { return PhysicalDisplayId(0, port, kManufacturerId, kModelHash); } - // TODO(b/162612135) Remove default constructor - PhysicalDisplayId() = default; - - constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); } - constexpr uint8_t getPort() const { return static_cast<uint8_t>(value); } + static constexpr PhysicalDisplayId fromValue(uint64_t value) { + return PhysicalDisplayId(value); + } private: + // Flag indicating that the ID is stable across reboots. + static constexpr uint64_t FLAG_STABLE = 1ULL << 62; + + using DisplayId::DisplayId; + constexpr PhysicalDisplayId(uint64_t flags, uint8_t port, uint16_t manufacturerId, uint32_t modelHash) : DisplayId(flags | (static_cast<uint64_t>(manufacturerId) << 40) | @@ -120,55 +103,38 @@ struct VirtualDisplayId : DisplayId { // Flag indicating that this virtual display is backed by the GPU. static constexpr uint64_t FLAG_GPU = 1ULL << 61; - static constexpr std::optional<VirtualDisplayId> tryCast(DisplayId id) { - if (id.isVirtual()) { - return VirtualDisplayId(id); - } - return std::nullopt; + static constexpr VirtualDisplayId fromValue(uint64_t value) { + return VirtualDisplayId(SkipVirtualFlag{}, value); } protected: + struct SkipVirtualFlag {}; + constexpr VirtualDisplayId(SkipVirtualFlag, uint64_t value) : DisplayId(value) {} explicit constexpr VirtualDisplayId(uint64_t value) : DisplayId(FLAG_VIRTUAL | value) {} + explicit constexpr VirtualDisplayId(DisplayId other) : DisplayId(other) {} }; struct HalVirtualDisplayId : VirtualDisplayId { explicit constexpr HalVirtualDisplayId(BaseId baseId) : VirtualDisplayId(baseId) {} - static constexpr std::optional<HalVirtualDisplayId> tryCast(DisplayId id) { - if (id.isVirtual() && !(id.value & FLAG_GPU)) { - return HalVirtualDisplayId(id); - } - return std::nullopt; + static constexpr HalVirtualDisplayId fromValue(uint64_t value) { + return HalVirtualDisplayId(SkipVirtualFlag{}, value); } private: - explicit constexpr HalVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {} + using VirtualDisplayId::VirtualDisplayId; }; struct GpuVirtualDisplayId : VirtualDisplayId { explicit constexpr GpuVirtualDisplayId(BaseId baseId) : VirtualDisplayId(FLAG_GPU | baseId) {} - static constexpr std::optional<GpuVirtualDisplayId> fromUniqueId(const std::string& uniqueId) { - if (const auto hashOpt = ftl::stable_hash(uniqueId)) { - return GpuVirtualDisplayId(HashTag{}, *hashOpt); - } - return {}; - } - - static constexpr std::optional<GpuVirtualDisplayId> tryCast(DisplayId id) { - if (id.isVirtual() && (id.value & FLAG_GPU)) { - return GpuVirtualDisplayId(id); - } - return std::nullopt; + static constexpr GpuVirtualDisplayId fromValue(uint64_t value) { + return GpuVirtualDisplayId(SkipVirtualFlag{}, value); } private: - struct HashTag {}; // Disambiguate with BaseId constructor. - constexpr GpuVirtualDisplayId(HashTag, uint64_t hash) - : VirtualDisplayId(FLAG_STABLE | FLAG_GPU | hash) {} - - explicit constexpr GpuVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {} + using VirtualDisplayId::VirtualDisplayId; }; // HalDisplayId is the ID of a display which is managed by HWC. @@ -176,26 +142,52 @@ private: struct HalDisplayId : DisplayId { constexpr HalDisplayId(HalVirtualDisplayId other) : DisplayId(other) {} constexpr HalDisplayId(PhysicalDisplayId other) : DisplayId(other) {} - - static constexpr std::optional<HalDisplayId> tryCast(DisplayId id) { - if (GpuVirtualDisplayId::tryCast(id)) { - return std::nullopt; - } - return HalDisplayId(id); - } + static constexpr HalDisplayId fromValue(uint64_t value) { return HalDisplayId(value); } private: + using DisplayId::DisplayId; explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {} }; -constexpr std::optional<DisplayId> DisplayId::fromValue(uint64_t value) { - if (const auto id = fromValue<PhysicalDisplayId>(value)) { - return id; - } - if (const auto id = fromValue<VirtualDisplayId>(value)) { - return id; - } - return {}; +using DisplayIdVariant = std::variant<PhysicalDisplayId, GpuVirtualDisplayId, HalVirtualDisplayId>; +using VirtualDisplayIdVariant = std::variant<GpuVirtualDisplayId, HalVirtualDisplayId>; + +template <typename DisplayIdType> +inline auto asDisplayIdOfType(DisplayIdVariant variant) -> ftl::Optional<DisplayIdType> { + return ftl::match( + variant, + [](DisplayIdType id) -> ftl::Optional<DisplayIdType> { return ftl::Optional(id); }, + [](auto) -> ftl::Optional<DisplayIdType> { return std::nullopt; }); +} + +template <typename Variant> +inline auto asHalDisplayId(Variant variant) -> ftl::Optional<HalDisplayId> { + return ftl::match( + variant, + [](GpuVirtualDisplayId) -> ftl::Optional<HalDisplayId> { return std::nullopt; }, + [](auto id) -> ftl::Optional<HalDisplayId> { + return ftl::Optional(static_cast<HalDisplayId>(id)); + }); +} + +inline auto asPhysicalDisplayId(DisplayIdVariant variant) -> ftl::Optional<PhysicalDisplayId> { + return asDisplayIdOfType<PhysicalDisplayId>(variant); +} + +inline auto asVirtualDisplayId(DisplayIdVariant variant) -> ftl::Optional<VirtualDisplayId> { + return ftl::match( + variant, + [](GpuVirtualDisplayId id) -> ftl::Optional<VirtualDisplayId> { + return ftl::Optional(static_cast<VirtualDisplayId>(id)); + }, + [](HalVirtualDisplayId id) -> ftl::Optional<VirtualDisplayId> { + return ftl::Optional(static_cast<VirtualDisplayId>(id)); + }, + [](auto) -> ftl::Optional<VirtualDisplayId> { return std::nullopt; }); +} + +inline auto asDisplayId(DisplayIdVariant variant) -> DisplayId { + return ftl::match(variant, [](auto id) -> DisplayId { return static_cast<DisplayId>(id); }); } static_assert(sizeof(DisplayId) == sizeof(uint64_t)); diff --git a/libs/ui/include/ui/DisplayIdentification.h b/libs/ui/include/ui/DisplayIdentification.h index cdac2698dd..1e3449c004 100644 --- a/libs/ui/include/ui/DisplayIdentification.h +++ b/libs/ui/include/ui/DisplayIdentification.h @@ -74,6 +74,7 @@ struct Edid { std::optional<uint64_t> hashedDescriptorBlockSerialNumberOpt; PnpId pnpId; uint32_t modelHash; + // Up to 13 characters of ASCII text terminated by LF and padded with SP. std::string_view displayName; uint8_t manufactureOrModelYear; uint8_t manufactureWeek; @@ -85,11 +86,14 @@ struct Edid { bool isEdid(const DisplayIdentificationData&); std::optional<Edid> parseEdid(const DisplayIdentificationData&); std::optional<PnpId> getPnpId(uint16_t manufacturerId); -std::optional<PnpId> getPnpId(PhysicalDisplayId); std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData( uint8_t port, const DisplayIdentificationData&); PhysicalDisplayId getVirtualDisplayId(uint32_t id); +// Generates a consistent, stable, and hashed display ID that is based on the +// display's parsed EDID fields. +PhysicalDisplayId generateEdidDisplayId(const Edid& edid); + } // namespace android diff --git a/libs/ui/include/ui/DisplayMap.h b/libs/ui/include/ui/DisplayMap.h index 65d2b8fa31..834a3042d1 100644 --- a/libs/ui/include/ui/DisplayMap.h +++ b/libs/ui/include/ui/DisplayMap.h @@ -18,6 +18,7 @@ #include <ftl/small_map.h> #include <ftl/small_vector.h> +#include <ftl/unit.h> namespace android::ui { @@ -30,6 +31,8 @@ using DisplayMap = ftl::SmallMap<Key, Value, kDisplayCapacity>; constexpr size_t kPhysicalDisplayCapacity = 3; template <typename Key, typename Value> using PhysicalDisplayMap = ftl::SmallMap<Key, Value, kPhysicalDisplayCapacity>; +template <typename Key> +using PhysicalDisplaySet = ftl::SmallMap<Key, ftl::Unit, kPhysicalDisplayCapacity>; template <typename T> using DisplayVector = ftl::SmallVector<T, kDisplayCapacity>; diff --git a/services/surfaceflinger/Utils/RingBuffer.h b/libs/ui/include/ui/RingBuffer.h index 215472b388..31d5a950ef 100644 --- a/services/surfaceflinger/Utils/RingBuffer.h +++ b/libs/ui/include/ui/RingBuffer.h @@ -19,7 +19,7 @@ #include <stddef.h> #include <array> -namespace android::utils { +namespace android::ui { template <class T, size_t SIZE> class RingBuffer { @@ -31,8 +31,8 @@ public: ~RingBuffer() = default; constexpr size_t capacity() const { return SIZE; } - size_t size() const { return mCount; } + bool isFull() const { return size() == capacity(); } T& next() { mHead = static_cast<size_t>(mHead + 1) % SIZE; @@ -67,4 +67,4 @@ private: size_t mCount = 0; }; -} // namespace android::utils +} // namespace android::ui diff --git a/libs/ui/include/ui/StaticDisplayInfo.h b/libs/ui/include/ui/StaticDisplayInfo.h index 83da821f37..53164487f3 100644 --- a/libs/ui/include/ui/StaticDisplayInfo.h +++ b/libs/ui/include/ui/StaticDisplayInfo.h @@ -28,6 +28,7 @@ enum class DisplayConnectionType { Internal, External, ftl_last = External }; // Immutable information about physical display. struct StaticDisplayInfo { DisplayConnectionType connectionType = DisplayConnectionType::Internal; + uint8_t port; float density = 0.f; bool secure = false; std::optional<DeviceProductInfo> deviceProductInfo; diff --git a/libs/ui/include_types/ui/HdrRenderTypeUtils.h b/libs/ui/include_types/ui/HdrRenderTypeUtils.h index 70c50f07e5..98018d95d1 100644 --- a/libs/ui/include_types/ui/HdrRenderTypeUtils.h +++ b/libs/ui/include_types/ui/HdrRenderTypeUtils.h @@ -36,7 +36,7 @@ enum class HdrRenderType { */ inline HdrRenderType getHdrRenderType(ui::Dataspace dataspace, std::optional<ui::PixelFormat> pixelFormat, - float hdrSdrRatio = 1.f) { + float hdrSdrRatio = 1.f, bool hasHdrMetadata = false) { const auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK; const auto range = dataspace & HAL_DATASPACE_RANGE_MASK; @@ -49,7 +49,8 @@ inline HdrRenderType getHdrRenderType(ui::Dataspace dataspace, HAL_DATASPACE_RANGE_EXTENDED); if ((dataspace == BT2020_LINEAR_EXT || dataspace == ui::Dataspace::V0_SCRGB) && - pixelFormat.has_value() && pixelFormat.value() == ui::PixelFormat::RGBA_FP16) { + pixelFormat.has_value() && pixelFormat.value() == ui::PixelFormat::RGBA_FP16 && + hasHdrMetadata) { return HdrRenderType::GENERIC_HDR; } diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp index 2d8a1e326c..d950f2a23f 100644 --- a/libs/ui/tests/Android.bp +++ b/libs/ui/tests/Android.bp @@ -45,16 +45,6 @@ cc_test { } cc_test { - name: "DisplayId_test", - shared_libs: ["libui"], - srcs: ["DisplayId_test.cpp"], - cflags: [ - "-Wall", - "-Werror", - ], -} - -cc_test { name: "DisplayIdentification_test", shared_libs: ["libui"], static_libs: ["libgmock"], @@ -144,6 +134,17 @@ cc_test { } cc_test { + name: "RingBuffer_test", + test_suites: ["device-tests"], + shared_libs: ["libui"], + srcs: ["RingBuffer_test.cpp"], + cflags: [ + "-Wall", + "-Werror", + ], +} + +cc_test { name: "Size_test", test_suites: ["device-tests"], shared_libs: ["libui"], diff --git a/libs/ui/tests/DisplayId_test.cpp b/libs/ui/tests/DisplayId_test.cpp deleted file mode 100644 index ef686dfc83..0000000000 --- a/libs/ui/tests/DisplayId_test.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <ui/DisplayId.h> - -#include <gtest/gtest.h> - -namespace android::ui { - -TEST(DisplayIdTest, createPhysicalIdFromEdid) { - constexpr uint8_t port = 1; - constexpr uint16_t manufacturerId = 13; - constexpr uint32_t modelHash = 42; - const PhysicalDisplayId id = PhysicalDisplayId::fromEdid(port, manufacturerId, modelHash); - EXPECT_EQ(port, id.getPort()); - EXPECT_EQ(manufacturerId, id.getManufacturerId()); - EXPECT_FALSE(VirtualDisplayId::tryCast(id)); - EXPECT_FALSE(HalVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id)); - EXPECT_TRUE(PhysicalDisplayId::tryCast(id)); - EXPECT_TRUE(HalDisplayId::tryCast(id)); - - EXPECT_EQ(id, DisplayId::fromValue(id.value)); - EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value)); -} - -TEST(DisplayIdTest, createPhysicalIdFromPort) { - constexpr uint8_t port = 3; - const PhysicalDisplayId id = PhysicalDisplayId::fromPort(port); - EXPECT_EQ(port, id.getPort()); - EXPECT_FALSE(VirtualDisplayId::tryCast(id)); - EXPECT_FALSE(HalVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id)); - EXPECT_TRUE(PhysicalDisplayId::tryCast(id)); - EXPECT_TRUE(HalDisplayId::tryCast(id)); - - EXPECT_EQ(id, DisplayId::fromValue(id.value)); - EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value)); -} - -TEST(DisplayIdTest, createGpuVirtualId) { - const GpuVirtualDisplayId id(42); - EXPECT_TRUE(VirtualDisplayId::tryCast(id)); - EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(HalVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(PhysicalDisplayId::tryCast(id)); - EXPECT_FALSE(HalDisplayId::tryCast(id)); - - EXPECT_EQ(id, DisplayId::fromValue(id.value)); - EXPECT_EQ(id, DisplayId::fromValue<GpuVirtualDisplayId>(id.value)); -} - -TEST(DisplayIdTest, createVirtualIdFromGpuVirtualId) { - const VirtualDisplayId id(GpuVirtualDisplayId(42)); - EXPECT_TRUE(VirtualDisplayId::tryCast(id)); - EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(HalVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(PhysicalDisplayId::tryCast(id)); - EXPECT_FALSE(HalDisplayId::tryCast(id)); - - const bool isGpuVirtualId = (id.value & VirtualDisplayId::FLAG_GPU); - EXPECT_EQ((id.isVirtual() && isGpuVirtualId), GpuVirtualDisplayId::tryCast(id).has_value()); -} - -TEST(DisplayIdTest, createGpuVirtualIdFromUniqueId) { - static const std::string kUniqueId("virtual:ui:DisplayId_test"); - const auto idOpt = GpuVirtualDisplayId::fromUniqueId(kUniqueId); - ASSERT_TRUE(idOpt.has_value()); - const GpuVirtualDisplayId id = idOpt.value(); - EXPECT_TRUE(VirtualDisplayId::tryCast(id)); - EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(HalVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(PhysicalDisplayId::tryCast(id)); - EXPECT_FALSE(HalDisplayId::tryCast(id)); - - EXPECT_EQ(id, DisplayId::fromValue(id.value)); - EXPECT_EQ(id, DisplayId::fromValue<GpuVirtualDisplayId>(id.value)); -} - -TEST(DisplayIdTest, createHalVirtualId) { - const HalVirtualDisplayId id(42); - EXPECT_TRUE(VirtualDisplayId::tryCast(id)); - EXPECT_TRUE(HalVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(PhysicalDisplayId::tryCast(id)); - EXPECT_TRUE(HalDisplayId::tryCast(id)); - - EXPECT_EQ(id, DisplayId::fromValue(id.value)); - EXPECT_EQ(id, DisplayId::fromValue<HalVirtualDisplayId>(id.value)); -} - -TEST(DisplayIdTest, createVirtualIdFromHalVirtualId) { - const VirtualDisplayId id(HalVirtualDisplayId(42)); - EXPECT_TRUE(VirtualDisplayId::tryCast(id)); - EXPECT_TRUE(HalVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id)); - EXPECT_FALSE(PhysicalDisplayId::tryCast(id)); - EXPECT_TRUE(HalDisplayId::tryCast(id)); - - const bool isGpuVirtualId = (id.value & VirtualDisplayId::FLAG_GPU); - EXPECT_EQ((id.isVirtual() && !isGpuVirtualId), HalVirtualDisplayId::tryCast(id).has_value()); -} - -} // namespace android::ui diff --git a/libs/ui/tests/DisplayIdentification_test.cpp b/libs/ui/tests/DisplayIdentification_test.cpp index d1699e79b6..75c71a598e 100644 --- a/libs/ui/tests/DisplayIdentification_test.cpp +++ b/libs/ui/tests/DisplayIdentification_test.cpp @@ -376,6 +376,22 @@ TEST(DisplayIdentificationTest, parseDisplayIdentificationData) { EXPECT_EQ(4633127902230889474, tertiaryInfo->id.value); } +TEST(DisplayIdentificationTest, generateEdidDisplayId) { + const auto firstExternalDisplayEdidOpt = parseEdid(getExternalEdid()); + ASSERT_TRUE(firstExternalDisplayEdidOpt); + const PhysicalDisplayId firstExternalDisplayId = + generateEdidDisplayId(firstExternalDisplayEdidOpt.value()); + + const auto secondExternalDisplayEdidOpt = parseEdid(getExternalEedid()); + ASSERT_TRUE(secondExternalDisplayEdidOpt); + const PhysicalDisplayId secondExternalDisplayId = + generateEdidDisplayId(secondExternalDisplayEdidOpt.value()); + + // Display IDs should be unique. + EXPECT_EQ(4067182673952280501u, firstExternalDisplayId.value); + EXPECT_EQ(14712168404707886855u, secondExternalDisplayId.value); +} + TEST(DisplayIdentificationTest, deviceProductInfo) { using ManufactureYear = DeviceProductInfo::ManufactureYear; using ManufactureWeekAndYear = DeviceProductInfo::ManufactureWeekAndYear; @@ -462,18 +478,6 @@ TEST(DisplayIdentificationTest, deviceProductInfo) { } } -TEST(DisplayIdentificationTest, fromPort) { - // Manufacturer ID should be invalid. - ASSERT_FALSE(getPnpId(PhysicalDisplayId::fromPort(0))); - ASSERT_FALSE(getPnpId(PhysicalDisplayId::fromPort(0xffu))); -} - -TEST(DisplayIdentificationTest, getVirtualDisplayId) { - // Manufacturer ID should be invalid. - ASSERT_FALSE(getPnpId(getVirtualDisplayId(0))); - ASSERT_FALSE(getPnpId(getVirtualDisplayId(0xffff'ffffu))); -} - } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/libs/ui/tests/RingBuffer_test.cpp b/libs/ui/tests/RingBuffer_test.cpp new file mode 100644 index 0000000000..9839492b9f --- /dev/null +++ b/libs/ui/tests/RingBuffer_test.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> +#include <ui/RingBuffer.h> + +namespace android::ui { + +TEST(RingBuffer, basic) { + RingBuffer<int, 5> rb; + + rb.next() = 1; + ASSERT_EQ(1, rb.size()); + ASSERT_EQ(1, rb.back()); + ASSERT_EQ(1, rb.front()); + + rb.next() = 2; + ASSERT_EQ(2, rb.size()); + ASSERT_EQ(2, rb.back()); + ASSERT_EQ(1, rb.front()); + ASSERT_EQ(1, rb[-1]); + + rb.next() = 3; + ASSERT_EQ(3, rb.size()); + ASSERT_EQ(3, rb.back()); + ASSERT_EQ(1, rb.front()); + ASSERT_EQ(2, rb[-1]); + ASSERT_EQ(1, rb[-2]); + + rb.next() = 4; + ASSERT_EQ(4, rb.size()); + ASSERT_EQ(4, rb.back()); + ASSERT_EQ(1, rb.front()); + ASSERT_EQ(3, rb[-1]); + ASSERT_EQ(2, rb[-2]); + ASSERT_EQ(1, rb[-3]); + + rb.next() = 5; + ASSERT_EQ(5, rb.size()); + ASSERT_EQ(5, rb.back()); + ASSERT_EQ(1, rb.front()); + ASSERT_EQ(4, rb[-1]); + ASSERT_EQ(3, rb[-2]); + ASSERT_EQ(2, rb[-3]); + ASSERT_EQ(1, rb[-4]); + + rb.next() = 6; + ASSERT_EQ(5, rb.size()); + ASSERT_EQ(6, rb.back()); + ASSERT_EQ(2, rb.front()); + ASSERT_EQ(5, rb[-1]); + ASSERT_EQ(4, rb[-2]); + ASSERT_EQ(3, rb[-3]); + ASSERT_EQ(2, rb[-4]); +} + +} // namespace android::ui
\ No newline at end of file diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp index 91250b9945..eb747c767e 100644 --- a/opengl/libs/Android.bp +++ b/opengl/libs/Android.bp @@ -8,6 +8,11 @@ package { default_applicable_licenses: ["frameworks_native_license"], } +cc_aconfig_library { + name: "libegl_flags_c_lib", + aconfig_declarations: "graphicsenv_flags", +} + cc_library { name: "libETC1", srcs: ["ETC1/etc1.cpp"], @@ -155,7 +160,10 @@ cc_library_static { cc_library_shared { name: "libEGL", - defaults: ["egl_libs_defaults"], + defaults: [ + "aconfig_lib_cc_static_link.defaults", + "egl_libs_defaults", + ], llndk: { symbol_file: "libEGL.map.txt", export_llndk_headers: ["gl_headers"], @@ -191,6 +199,7 @@ cc_library_shared { static_libs: [ "libEGL_getProcAddress", "libEGL_blobCache", + "libegl_flags_c_lib", ], ldflags: [ "-Wl,--exclude-libs=libEGL_getProcAddress.a", diff --git a/opengl/libs/EGL/MultifileBlobCache.cpp b/opengl/libs/EGL/MultifileBlobCache.cpp index 04c525e93d..7faf361c08 100644 --- a/opengl/libs/EGL/MultifileBlobCache.cpp +++ b/opengl/libs/EGL/MultifileBlobCache.cpp @@ -356,7 +356,7 @@ void MultifileBlobCache::set(const void* key, EGLsizeiANDROID keySize, const voi // If we're going to be over the cache limit, kick off a trim to clear space if (getTotalSize() + fileSize > mMaxTotalSize || getTotalEntries() + 1 > mMaxTotalEntries) { - ALOGV("SET: Cache is full, calling trimCache to clear space"); + ALOGW("SET: Cache is full, calling trimCache to clear space"); trimCache(); } diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp index b1a287fcec..efc34f6aa8 100644 --- a/opengl/libs/EGL/egl_display.cpp +++ b/opengl/libs/EGL/egl_display.cpp @@ -22,6 +22,7 @@ #include <android-base/properties.h> #include <android/dlext.h> #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> +#include <com_android_graphics_graphicsenv_flags.h> #include <configstore/Utils.h> #include <dlfcn.h> #include <graphicsenv/GraphicsEnv.h> @@ -37,6 +38,7 @@ using namespace android::hardware::configstore; using namespace android::hardware::configstore::V1_0; +namespace graphicsenv_flags = com::android::graphics::graphicsenv::flags; namespace android { @@ -132,21 +134,47 @@ static EGLDisplay getPlatformDisplayAngle(EGLNativeDisplayType display, egl_conn if (cnx->egl.eglGetPlatformDisplay) { std::vector<EGLAttrib> attrs; + // These must have the same lifetime as |attrs|, because |attrs| contains pointers to these + // variables. + std::vector<const char*> enabled; // ANGLE features to enable + std::vector<const char*> disabled; // ANGLE features to disable + if (attrib_list) { for (const EGLAttrib* attr = attrib_list; *attr != EGL_NONE; attr += 2) { attrs.push_back(attr[0]); attrs.push_back(attr[1]); } } - const auto& eglFeatures = GraphicsEnv::getInstance().getAngleEglFeatures(); - std::vector<const char*> features; - if (eglFeatures.size() > 0) { + + if (graphicsenv_flags::angle_feature_overrides()) { + // Get the list of ANGLE features to enable from Global.Settings. + const auto& eglFeatures = GraphicsEnv::getInstance().getAngleEglFeatures(); for (const std::string& eglFeature : eglFeatures) { - features.push_back(eglFeature.c_str()); + enabled.push_back(eglFeature.c_str()); + } + + // Get the list of ANGLE features to enable/disable from gpuservice. + GraphicsEnv::getInstance().getAngleFeatureOverrides(enabled, disabled); + if (!enabled.empty()) { + enabled.push_back(nullptr); + attrs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE); + attrs.push_back(reinterpret_cast<EGLAttrib>(enabled.data())); + } + if (!disabled.empty()) { + disabled.push_back(nullptr); + attrs.push_back(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE); + attrs.push_back(reinterpret_cast<EGLAttrib>(disabled.data())); + } + } else { + const auto& eglFeatures = GraphicsEnv::getInstance().getAngleEglFeatures(); + if (!eglFeatures.empty()) { + for (const std::string& eglFeature : eglFeatures) { + enabled.push_back(eglFeature.c_str()); + } + enabled.push_back(nullptr); + attrs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE); + attrs.push_back(reinterpret_cast<EGLAttrib>(enabled.data())); } - features.push_back(0); - attrs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE); - attrs.push_back(reinterpret_cast<EGLAttrib>(features.data())); } attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE); diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp index 839a5cab2f..ebdc629caa 100644 --- a/opengl/tests/EGLTest/EGL_test.cpp +++ b/opengl/tests/EGLTest/EGL_test.cpp @@ -141,7 +141,7 @@ TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) { }; EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs)); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -261,7 +261,7 @@ TEST_F(EGLTest, EGLDisplayP3) { EXPECT_EQ(components[2], 8); EXPECT_EQ(components[3], 8); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -309,7 +309,7 @@ TEST_F(EGLTest, EGLDisplayP3Passthrough) { get8BitConfig(config); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -406,7 +406,7 @@ TEST_F(EGLTest, EGLDisplayP31010102) { EXPECT_EQ(components[2], 10); EXPECT_EQ(components[3], 2); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -578,7 +578,7 @@ TEST_F(EGLTest, EGLBT2020Linear) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -630,7 +630,7 @@ TEST_F(EGLTest, EGLBT2020PQ) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -713,7 +713,7 @@ TEST_F(EGLTest, EGLConfigFP16) { EXPECT_GE(components[2], 16); EXPECT_GE(components[3], 16); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -742,7 +742,7 @@ TEST_F(EGLTest, EGLNoConfigContext) { ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context")); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -841,7 +841,7 @@ TEST_F(EGLTest, EGLConfig1010102) { EXPECT_EQ(components[2], 10); EXPECT_EQ(components[3], 2); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -867,7 +867,7 @@ TEST_F(EGLTest, EGLInvalidColorspaceAttribute) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -920,7 +920,7 @@ TEST_F(EGLTest, EGLUnsupportedColorspaceFormatCombo) { ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(1, numConfigs); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -951,7 +951,7 @@ TEST_F(EGLTest, EGLCreateWindowFailAndSucceed) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -997,7 +997,7 @@ TEST_F(EGLTest, EGLCreateWindowTwoColorspaces) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct MockConsumer : public BnConsumerListener { + struct MockConsumer : public IConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp index 7c255ed106..5ba72affc0 100644 --- a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp +++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp @@ -113,7 +113,7 @@ not_valid_surface: if (producer == NULL) goto not_valid_surface; - window = new android::Surface(producer, true); + window = android::sp<android::Surface>::make(producer, true); if (window == NULL) goto not_valid_surface; diff --git a/services/audiomanager/Android.bp b/services/audiomanager/Android.bp index d11631b783..afcdf742c9 100644 --- a/services/audiomanager/Android.bp +++ b/services/audiomanager/Android.bp @@ -15,6 +15,7 @@ cc_library { ], shared_libs: [ + "av-types-aidl-cpp", "libutils", "libbinder", "liblog", diff --git a/services/audiomanager/IAudioManager.cpp b/services/audiomanager/IAudioManager.cpp index f8a38d1e38..8db9a78f7f 100644 --- a/services/audiomanager/IAudioManager.cpp +++ b/services/audiomanager/IAudioManager.cpp @@ -35,6 +35,24 @@ public: { } + virtual sp<media::IAudioManagerNative> getNativeInterface() { + Parcel data, reply; + data.writeInterfaceToken(IAudioManager::getInterfaceDescriptor()); + const status_t res = remote()->transact(GET_NATIVE_INTERFACE, data, &reply, 0); + if (res == DEAD_OBJECT) return nullptr; + LOG_ALWAYS_FATAL_IF(res != OK, "%s failed with result %d", __func__, res); + const int ex = reply.readExceptionCode(); + LOG_ALWAYS_FATAL_IF(ex != binder::Status::EX_NONE, "%s failed with exception %d", + __func__, + ex); + sp<IBinder> binder; + const status_t err = reply.readNullableStrongBinder(&binder); + LOG_ALWAYS_FATAL_IF(binder == nullptr, "%s failed unexpected nullptr %d", __func__, err); + const auto iface = checked_interface_cast<media::IAudioManagerNative>(binder); + LOG_ALWAYS_FATAL_IF(iface == nullptr, "%s failed unexpected interface", __func__); + return iface; + } + virtual audio_unique_id_t trackPlayer(player_type_t playerType, audio_usage_t usage, audio_content_type_t content, const sp<IBinder>& player, audio_session_t sessionId) { Parcel data, reply; diff --git a/services/automotive/display/AutomotiveDisplayProxyService.cpp b/services/automotive/display/AutomotiveDisplayProxyService.cpp index d205231033..afa623352b 100644 --- a/services/automotive/display/AutomotiveDisplayProxyService.cpp +++ b/services/automotive/display/AutomotiveDisplayProxyService.cpp @@ -34,10 +34,8 @@ AutomotiveDisplayProxyService::getIGraphicBufferProducer(uint64_t id) { sp<IBinder> displayToken = nullptr; sp<SurfaceControl> surfaceControl = nullptr; if (it == mDisplays.end()) { - if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) { - displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId); - } - + displayToken = + SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId::fromValue(id)); if (displayToken == nullptr) { ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id); return nullptr; @@ -160,11 +158,8 @@ Return<void> AutomotiveDisplayProxyService::getDisplayInfo(uint64_t id, getDispl HwDisplayConfig activeConfig; HwDisplayState activeState; - sp<IBinder> displayToken; - if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) { - displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId); - } - + sp<IBinder> displayToken = + SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId::fromValue(id)); if (displayToken == nullptr) { ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id); } else { @@ -197,4 +192,3 @@ Return<void> AutomotiveDisplayProxyService::getDisplayInfo(uint64_t id, getDispl } // namespace automotive } // namespace frameworks } // namespace android - diff --git a/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc b/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc index 5c7f344486..e96b17a2de 100644 --- a/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc +++ b/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc @@ -2,3 +2,4 @@ service automotive_display /system/bin/android.frameworks.automotive.display@1.0 class hal user graphics group automotive_evs + disabled diff --git a/services/displayservice/DisplayEventReceiver.cpp b/services/displayservice/DisplayEventReceiver.cpp index 2bb74c2cad..9927fb66d3 100644 --- a/services/displayservice/DisplayEventReceiver.cpp +++ b/services/displayservice/DisplayEventReceiver.cpp @@ -22,6 +22,7 @@ #include <android/frameworks/displayservice/1.0/BpHwEventCallback.h> #include <thread> +#include <ftl/enum.h> namespace android { namespace frameworks { @@ -97,11 +98,11 @@ int DisplayEventReceiver::AttachedEvent::handleEvent(int fd, int events, void* / for (size_t i = 0; i < static_cast<size_t>(n); ++i) { const FwkReceiver::Event &event = buf[i]; - uint32_t type = event.header.type; + android::DisplayEventType type = event.header.type; uint64_t timestamp = event.header.timestamp; switch(buf[i].header.type) { - case FwkReceiver::DISPLAY_EVENT_VSYNC: { + case DisplayEventType::DISPLAY_EVENT_VSYNC: { auto ret = mCallback->onVsync(timestamp, event.vsync.count); if (!ret.isOk()) { LOG(ERROR) << "AttachedEvent handleEvent fails on onVsync callback" @@ -109,7 +110,7 @@ int DisplayEventReceiver::AttachedEvent::handleEvent(int fd, int events, void* / return 0; // remove the callback } } break; - case FwkReceiver::DISPLAY_EVENT_HOTPLUG: { + case DisplayEventType::DISPLAY_EVENT_HOTPLUG: { auto ret = mCallback->onHotplug(timestamp, event.hotplug.connected); if (!ret.isOk()) { LOG(ERROR) << "AttachedEvent handleEvent fails on onHotplug callback" @@ -118,7 +119,8 @@ int DisplayEventReceiver::AttachedEvent::handleEvent(int fd, int events, void* / } } break; default: { - LOG(ERROR) << "AttachedEvent handleEvent unknown type: " << type; + LOG(ERROR) << "AttachedEvent handleEvent unknown type: " + << ftl::to_underlying(type); } } } diff --git a/services/displayservice/OWNERS b/services/displayservice/OWNERS index 7a3e4c266f..40164aae0c 100644 --- a/services/displayservice/OWNERS +++ b/services/displayservice/OWNERS @@ -1,2 +1 @@ smoreland@google.com -lpy@google.com diff --git a/services/gpuservice/Android.bp b/services/gpuservice/Android.bp index ca9fe5ea43..74e354f09c 100644 --- a/services/gpuservice/Android.bp +++ b/services/gpuservice/Android.bp @@ -7,6 +7,13 @@ package { default_applicable_licenses: ["frameworks_native_license"], } +aconfig_declarations { + name: "gpuservice_flags", + package: "com.android.frameworks.gpuservice.flags", + container: "system", + srcs: ["gpuservice_flags.aconfig"], +} + cc_defaults { name: "gpuservice_defaults", cflags: [ @@ -19,10 +26,22 @@ cc_defaults { ], } +cc_aconfig_library { + name: "gpuservice_multiuser_flags_c_lib", + aconfig_declarations: "gpuservice_flags", +} + +cc_aconfig_library { + name: "gpuservice_flags_c_lib", + aconfig_declarations: "graphicsenv_flags", +} + cc_defaults { name: "libgpuservice_defaults", defaults: [ + "aconfig_lib_cc_static_link.defaults", "gpuservice_defaults", + "libfeatureoverride_deps", "libgfxstats_deps", "libgpumem_deps", "libgpumemtracer_deps", @@ -40,8 +59,11 @@ cc_defaults { "libgraphicsenv", "liblog", "libutils", + "server_configurable_flags", ], static_libs: [ + "gpuservice_flags_c_lib", + "libfeatureoverride", "libgfxstats", "libgpumem", "libgpumemtracer", @@ -83,6 +105,9 @@ cc_library_static { srcs: [ ":libgpuservice_sources", ], + shared_libs: [ + "gpuservice_multiuser_flags_c_lib", + ], } cc_defaults { @@ -117,4 +142,7 @@ cc_binary { static_libs: [ "libgpuservice", ], + shared_libs: [ + "gpuservice_multiuser_flags_c_lib", + ], } diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp index fadb1fd426..46327dfbe7 100644 --- a/services/gpuservice/GpuService.cpp +++ b/services/gpuservice/GpuService.cpp @@ -24,7 +24,11 @@ #include <binder/IResultReceiver.h> #include <binder/Parcel.h> #include <binder/PermissionCache.h> +#include <com_android_frameworks_gpuservice_flags.h> +#include <com_android_graphics_graphicsenv_flags.h> #include <cutils/properties.h> +#include <cutils/multiuser.h> +#include <feature_override/FeatureOverrideParser.h> #include <gpumem/GpuMem.h> #include <gpuwork/GpuWork.h> #include <gpustats/GpuStats.h> @@ -38,6 +42,9 @@ #include <thread> #include <memory> +namespace gpuservice_flags = com::android::frameworks::gpuservice::flags; +namespace graphicsenv_flags = com::android::graphics::graphicsenv::flags; + namespace android { using base::StringAppendF; @@ -113,11 +120,22 @@ void GpuService::toggleAngleAsSystemDriver(bool enabled) { // only system_server with the ACCESS_GPU_SERVICE permission is allowed to set // persist.graphics.egl - if (uid != AID_SYSTEM || - !PermissionCache::checkPermission(sAccessGpuServicePermission, pid, uid)) { - ALOGE("Permission Denial: can't set persist.graphics.egl from setAngleAsSystemDriver() " + if (gpuservice_flags::multiuser_permission_check()) { + // retrieve the appid of Settings app on multiuser builds + const int multiuserappid = multiuser_get_app_id(uid); + if (multiuserappid != AID_SYSTEM || + !PermissionCache::checkPermission(sAccessGpuServicePermission, pid, uid)) { + ALOGE("Permission Denial: can't set persist.graphics.egl from setAngleAsSystemDriver() " + "pid=%d, uid=%d\n, multiuserappid=%d", pid, uid, multiuserappid); + return; + } + } else { + if (uid != AID_SYSTEM || + !PermissionCache::checkPermission(sAccessGpuServicePermission, pid, uid)) { + ALOGE("Permission Denial: can't set persist.graphics.egl from setAngleAsSystemDriver() " "pid=%d, uid=%d\n", pid, uid); - return; + return; + } } std::lock_guard<std::mutex> lock(mLock); @@ -128,6 +146,14 @@ void GpuService::toggleAngleAsSystemDriver(bool enabled) { } } +FeatureOverrides GpuService::getFeatureOverrides() { + if (!graphicsenv_flags::angle_feature_overrides()) { + FeatureOverrides featureOverrides; + return featureOverrides; + } + + return mFeatureOverrideParser.getFeatureOverrides(); +} void GpuService::setUpdatableDriverPath(const std::string& driverPath) { IPCThreadState* ipc = IPCThreadState::self(); @@ -156,7 +182,11 @@ status_t GpuService::shellCommand(int /*in*/, int out, int err, std::vector<Stri for (size_t i = 0, n = args.size(); i < n; i++) ALOGV(" arg[%zu]: '%s'", i, String8(args[i]).c_str()); - if (args.size() >= 1) { + if (!args.empty()) { + if (graphicsenv_flags::angle_feature_overrides()) { + if (args[0] == String16("featureOverrides")) + return cmdFeatureOverrides(out, err); + } if (args[0] == String16("vkjson")) return cmdVkjson(out, err); if (args[0] == String16("vkprofiles")) return cmdVkprofiles(out, err); if (args[0] == String16("help")) return cmdHelp(out); @@ -220,6 +250,11 @@ status_t GpuService::doDump(int fd, const Vector<String16>& args, bool /*asProto return NO_ERROR; } +status_t GpuService::cmdFeatureOverrides(int out, int /*err*/) { + dprintf(out, "%s\n", mFeatureOverrideParser.getFeatureOverrides().toString().c_str()); + return NO_ERROR; +} + namespace { status_t cmdHelp(int out) { @@ -232,6 +267,10 @@ status_t cmdHelp(int out) { "GPU Service commands:\n" " vkjson dump Vulkan properties as JSON\n" " vkprofiles print support for select Vulkan profiles\n"); + if (graphicsenv_flags::angle_feature_overrides()) { + fprintf(outs, + " featureOverrides update and output gpuservice's feature overrides\n"); + } fclose(outs); return NO_ERROR; } diff --git a/services/gpuservice/OWNERS b/services/gpuservice/OWNERS index 07c681f1f4..a3afca5c1a 100644 --- a/services/gpuservice/OWNERS +++ b/services/gpuservice/OWNERS @@ -1,7 +1,4 @@ chrisforbes@google.com -lpy@google.com -alecmouri@google.com -lfy@google.com -paulthomson@google.com -pbaiget@google.com -kocdemir@google.com +tomnom@google.com + +alecmouri@google.com #{LAST_RESORT_SUGGESTION} diff --git a/services/gpuservice/feature_override/Android.bp b/services/gpuservice/feature_override/Android.bp new file mode 100644 index 0000000000..842a0c46d2 --- /dev/null +++ b/services/gpuservice/feature_override/Android.bp @@ -0,0 +1,100 @@ +// Copyright 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_native_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_native_license"], +} + +cc_defaults { + name: "libfeatureoverride_deps", + include_dirs: [ + "external/protobuf", + "external/protobuf/src", + ], + header_libs: [ + "libbase_headers", + ], + shared_libs: [ + "libbase", + "libgraphicsenv", + "liblog", + "libprotobuf-cpp-lite", + ], +} + +filegroup { + name: "feature_config_proto_definitions", + srcs: [ + "proto/feature_config.proto", + ], +} + +genrule { + name: "feature_config_proto_lite_gen_headers", + srcs: [ + ":feature_config_proto_definitions", + ], + tools: [ + "aprotoc", + ], + cmd: "$(location aprotoc) " + + "--proto_path=frameworks/native/services/gpuservice/feature_override " + + "--cpp_out=lite=true:$(genDir)/frameworks/native/services/gpuservice/feature_override " + + "$(locations :feature_config_proto_definitions)", + out: [ + "frameworks/native/services/gpuservice/feature_override/proto/feature_config.pb.h", + ], + export_include_dirs: [ + "frameworks/native/services/gpuservice/feature_override/proto/", + ], +} + +cc_library_static { + name: "libfeatureoverride", + defaults: [ + "libfeatureoverride_deps", + "libvkjson_deps", + ], + srcs: [ + ":feature_config_proto_definitions", + "FeatureOverrideParser.cpp", + ], + local_include_dirs: [ + "include", + ], + cflags: [ + "-Wall", + "-Werror", + "-Wimplicit-fallthrough", + ], + cppflags: [ + "-Wno-sign-compare", + ], + static_libs: [ + "libvkjson", + ], + export_include_dirs: ["include"], + proto: { + type: "lite", + static: true, + }, + generated_headers: [ + "feature_config_proto_lite_gen_headers", + ], +} diff --git a/services/gpuservice/feature_override/FeatureOverrideParser.cpp b/services/gpuservice/feature_override/FeatureOverrideParser.cpp new file mode 100644 index 0000000000..26ff84a34c --- /dev/null +++ b/services/gpuservice/feature_override/FeatureOverrideParser.cpp @@ -0,0 +1,203 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <feature_override/FeatureOverrideParser.h> + +#include <chrono> +#include <fstream> +#include <sstream> +#include <string> +#include <sys/stat.h> +#include <vector> + +#include <android-base/macros.h> +#include <graphicsenv/FeatureOverrides.h> +#include <log/log.h> +#include <vkjson.h> + +#include "feature_config.pb.h" + +namespace { + +void resetFeatureOverrides(android::FeatureOverrides &featureOverrides) { + featureOverrides.mGlobalFeatures.clear(); + featureOverrides.mPackageFeatures.clear(); +} + +bool +gpuVendorIdMatches(const VkJsonInstance &vkJsonInstance, + const uint32_t &configVendorId) { + if (vkJsonInstance.devices.empty()) { + return false; + } + + // Always match the TEST Vendor ID + if (configVendorId == feature_override::GpuVendorID::VENDOR_ID_TEST) { + return true; + } + + // Always assume one GPU device. + uint32_t vendorID = vkJsonInstance.devices.front().properties.vendorID; + + return vendorID == configVendorId; +} + +bool +conditionsMet(const VkJsonInstance &vkJsonInstance, + const android::FeatureConfig &featureConfig) { + bool gpuVendorIdMatch = false; + + if (featureConfig.mGpuVendorIDs.empty()) { + gpuVendorIdMatch = true; + } else { + for (const auto &gpuVendorID: featureConfig.mGpuVendorIDs) { + if (gpuVendorIdMatches(vkJsonInstance, gpuVendorID)) { + gpuVendorIdMatch = true; + break; + } + } + } + + return gpuVendorIdMatch; +} + +void initFeatureConfig(android::FeatureConfig &featureConfig, + const feature_override::FeatureConfig &featureConfigProto) { + featureConfig.mFeatureName = featureConfigProto.feature_name(); + featureConfig.mEnabled = featureConfigProto.enabled(); + for (const auto &gpuVendorIdProto: featureConfigProto.gpu_vendor_ids()) { + featureConfig.mGpuVendorIDs.emplace_back(static_cast<uint32_t>(gpuVendorIdProto)); + } +} + +feature_override::FeatureOverrideProtos readFeatureConfigProtos(const std::string &configFilePath) { + feature_override::FeatureOverrideProtos overridesProtos; + + std::ifstream protobufBinaryFile(configFilePath.c_str()); + if (protobufBinaryFile.fail()) { + ALOGE("Failed to open feature config file: `%s`.", configFilePath.c_str()); + return overridesProtos; + } + + std::stringstream buffer; + buffer << protobufBinaryFile.rdbuf(); + std::string serializedConfig = buffer.str(); + std::vector<uint8_t> serialized( + reinterpret_cast<const uint8_t *>(serializedConfig.data()), + reinterpret_cast<const uint8_t *>(serializedConfig.data()) + + serializedConfig.size()); + + if (!overridesProtos.ParseFromArray(serialized.data(), + static_cast<int>(serialized.size()))) { + ALOGE("Failed to parse GpuConfig protobuf data."); + } + + return overridesProtos; +} + +} // namespace + +namespace android { + +std::string FeatureOverrideParser::getFeatureOverrideFilePath() const { + const std::string kConfigFilePath = "/system/etc/angle/feature_config_vk.binarypb"; + + return kConfigFilePath; +} + +bool FeatureOverrideParser::shouldReloadFeatureOverrides() const { + std::string configFilePath = getFeatureOverrideFilePath(); + + std::ifstream configFile(configFilePath); + if (!configFile.good()) { + return false; + } + + struct stat fileStat{}; + if (stat(configFilePath.c_str(), &fileStat) != 0) { + ALOGE("Error getting file information for '%s': %s", configFilePath.c_str(), + strerror(errno)); + // stat'ing the file failed, so return false since reading it will also likely fail. + return false; + } + + return fileStat.st_mtime > mLastProtobufReadTime; +} + +void FeatureOverrideParser::forceFileRead() { + mLastProtobufReadTime = 0; +} + +void FeatureOverrideParser::parseFeatureOverrides() { + const feature_override::FeatureOverrideProtos overridesProtos = readFeatureConfigProtos( + getFeatureOverrideFilePath()); + + // Clear out the stale values before adding the newly parsed data. + resetFeatureOverrides(mFeatureOverrides); + + if (overridesProtos.global_features().empty() && + overridesProtos.package_features().empty()) { + // No overrides to parse. + return; + } + + const VkJsonInstance vkJsonInstance = VkJsonGetInstance(); + + // Global feature overrides. + for (const auto &featureConfigProto: overridesProtos.global_features()) { + FeatureConfig featureConfig; + initFeatureConfig(featureConfig, featureConfigProto); + + if (conditionsMet(vkJsonInstance, featureConfig)) { + mFeatureOverrides.mGlobalFeatures.emplace_back(featureConfig); + } + } + + // App-specific feature overrides. + for (auto const &pkgConfigProto: overridesProtos.package_features()) { + const std::string &packageName = pkgConfigProto.package_name(); + + if (mFeatureOverrides.mPackageFeatures.count(packageName)) { + ALOGE("Package already has feature overrides! Skipping."); + continue; + } + + std::vector<FeatureConfig> featureConfigs; + for (const auto &featureConfigProto: pkgConfigProto.feature_configs()) { + FeatureConfig featureConfig; + initFeatureConfig(featureConfig, featureConfigProto); + + if (conditionsMet(vkJsonInstance, featureConfig)) { + featureConfigs.emplace_back(featureConfig); + } + } + + mFeatureOverrides.mPackageFeatures[packageName] = featureConfigs; + } + + mLastProtobufReadTime = std::chrono::system_clock::to_time_t( + std::chrono::system_clock::now()); +} + +FeatureOverrides FeatureOverrideParser::getFeatureOverrides() { + if (shouldReloadFeatureOverrides()) { + parseFeatureOverrides(); + } + + return mFeatureOverrides; +} + +} // namespace android diff --git a/services/gpuservice/feature_override/include/feature_override/FeatureOverrideParser.h b/services/gpuservice/feature_override/include/feature_override/FeatureOverrideParser.h new file mode 100644 index 0000000000..b1f1867d99 --- /dev/null +++ b/services/gpuservice/feature_override/include/feature_override/FeatureOverrideParser.h @@ -0,0 +1,49 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FEATURE_OVERRIDE_PARSER_H_ +#define FEATURE_OVERRIDE_PARSER_H_ + +#include <ctime> +#include <string> +#include <vector> + +#include <graphicsenv/FeatureOverrides.h> + +namespace android { + +class FeatureOverrideParser { +public: + FeatureOverrideParser() = default; + FeatureOverrideParser(const FeatureOverrideParser &) = default; + virtual ~FeatureOverrideParser() = default; + + FeatureOverrides getFeatureOverrides(); + void forceFileRead(); + +private: + bool shouldReloadFeatureOverrides() const; + void parseFeatureOverrides(); + // Allow FeatureOverrideParserMock to override with the unit test file's path. + virtual std::string getFeatureOverrideFilePath() const; + + std::time_t mLastProtobufReadTime = 0; + FeatureOverrides mFeatureOverrides; +}; + +} // namespace android + +#endif // FEATURE_OVERRIDE_PARSER_H_ diff --git a/services/gpuservice/feature_override/proto/feature_config.proto b/services/gpuservice/feature_override/proto/feature_config.proto new file mode 100644 index 0000000000..f28518778f --- /dev/null +++ b/services/gpuservice/feature_override/proto/feature_config.proto @@ -0,0 +1,82 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto3"; + +package feature_override; + +option optimize_for = LITE_RUNTIME; + +/** + * GPU Vendor IDs. + * Taken from: external/angle/src/libANGLE/renderer/driver_utils.h + */ +enum GpuVendorID +{ + // Test ID matches every GPU Vendor ID. + VENDOR_ID_TEST = 0; + VENDOR_ID_AMD = 0x1002; + VENDOR_ID_ARM = 0x13B5; + // Broadcom devices won't use PCI, but this is their Vulkan vendor id. + VENDOR_ID_BROADCOM = 0x14E4; + VENDOR_ID_GOOGLE = 0x1AE0; + VENDOR_ID_INTEL = 0x8086; + VENDOR_ID_MESA = 0x10005; + VENDOR_ID_MICROSOFT = 0x1414; + VENDOR_ID_NVIDIA = 0x10DE; + VENDOR_ID_POWERVR = 0x1010; + // This is Qualcomm PCI Vendor ID. + // Android doesn't have a PCI bus, but all we need is a unique id. + VENDOR_ID_QUALCOMM = 0x5143; + VENDOR_ID_SAMSUNG = 0x144D; + VENDOR_ID_VIVANTE = 0x9999; + VENDOR_ID_VMWARE = 0x15AD; + VENDOR_ID_VIRTIO = 0x1AF4; +} + +/** + * Feature Configuration + * feature_name: Feature name (see external/angle/include/platform/autogen/FeaturesVk_autogen.h). + * enabled: Either enable or disable the feature. + * gpu_vendor_ids: The GPU architectures this FeatureConfig applies to, if any. + */ +message FeatureConfig +{ + string feature_name = 1; + bool enabled = 2; + repeated GpuVendorID gpu_vendor_ids = 3; +} + +/** + * Package Configuration + * feature_configs: List of features configs for the package. + */ +message PackageConfig +{ + string package_name = 1; + repeated FeatureConfig feature_configs = 2; +} + +/** + * Feature Overrides + * global_features: Features to apply globally, for every package. + * package_features: Features to apply for individual packages. + */ +message FeatureOverrideProtos +{ + repeated FeatureConfig global_features = 1; + repeated PackageConfig package_features = 2; +} diff --git a/services/gpuservice/gpuservice_flags.aconfig b/services/gpuservice/gpuservice_flags.aconfig new file mode 100644 index 0000000000..be6a7bb231 --- /dev/null +++ b/services/gpuservice/gpuservice_flags.aconfig @@ -0,0 +1,12 @@ +package: "com.android.frameworks.gpuservice.flags" +container: "system" + +flag { + name: "multiuser_permission_check" + namespace: "gpu" + description: "Whether to consider headless system user mode/multiuser when checking toggleAngleAsSystemDriver permission." + bug: "389867658" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/services/gpuservice/include/gpuservice/GpuService.h b/services/gpuservice/include/gpuservice/GpuService.h index 3072885838..22be9a72b9 100644 --- a/services/gpuservice/include/gpuservice/GpuService.h +++ b/services/gpuservice/include/gpuservice/GpuService.h @@ -19,6 +19,8 @@ #include <binder/IInterface.h> #include <cutils/compiler.h> +#include <feature_override/FeatureOverrideParser.h> +#include <graphicsenv/FeatureOverrides.h> #include <graphicsenv/GpuStatsInfo.h> #include <graphicsenv/IGpuService.h> #include <serviceutils/PriorityDumper.h> @@ -63,6 +65,7 @@ private: const uint64_t* values, const uint32_t valueCount) override; void setUpdatableDriverPath(const std::string& driverPath) override; std::string getUpdatableDriverPath() override; + FeatureOverrides getFeatureOverrides() override; void toggleAngleAsSystemDriver(bool enabled) override; void addVulkanEngineName(const std::string& appPackageName, const uint64_t driverVersionCode, const char *engineName) override; @@ -85,6 +88,8 @@ private: status_t doDump(int fd, const Vector<String16>& args, bool asProto); + status_t cmdFeatureOverrides(int out, int /*err*/); + /* * Attributes */ @@ -96,6 +101,7 @@ private: std::string mDeveloperDriverPath; std::unique_ptr<std::thread> mGpuMemAsyncInitThread; std::unique_ptr<std::thread> mGpuWorkAsyncInitThread; + FeatureOverrideParser mFeatureOverrideParser; }; } // namespace android diff --git a/services/gpuservice/tests/fuzzers/Android.bp b/services/gpuservice/tests/fuzzers/Android.bp index d4d48c48ea..7be3253565 100644 --- a/services/gpuservice/tests/fuzzers/Android.bp +++ b/services/gpuservice/tests/fuzzers/Android.bp @@ -13,6 +13,9 @@ cc_fuzz { "libgpuservice", "liblog", ], + shared_libs: [ + "gpuservice_multiuser_flags_c_lib", + ], fuzz_config: { cc: [ "paulthomson@google.com", diff --git a/services/gpuservice/tests/unittests/Android.bp b/services/gpuservice/tests/unittests/Android.bp index 8056a2c601..0dac24d560 100644 --- a/services/gpuservice/tests/unittests/Android.bp +++ b/services/gpuservice/tests/unittests/Android.bp @@ -21,20 +21,75 @@ package { default_applicable_licenses: ["frameworks_native_license"], } +cc_aconfig_library { + name: "gpuservice_unittest_flags_c_lib", + aconfig_declarations: "graphicsenv_flags", +} + +genrule_defaults { + name: "gpuservice_unittest_feature_config_pb_defaults", + tools: ["aprotoc"], + tool_files: [ + ":feature_config_proto_definitions", + ], + cmd: "$(location aprotoc) " + + "--encode=feature_override.FeatureOverrideProtos " + + "$(locations :feature_config_proto_definitions) " + + "< $(in) " + + "> $(out) ", +} + +// Main protobuf used by the unit tests. +filegroup { + name: "gpuservice_unittest_feature_config_vk_prototext", + srcs: [ + "data/feature_config_test.txtpb", + ], +} + +genrule { + name: "gpuservice_unittest_feature_config_vk_binarypb", + defaults: ["gpuservice_unittest_feature_config_pb_defaults"], + srcs: [ + ":gpuservice_unittest_feature_config_vk_prototext", + ], + out: ["gpuservice_unittest_feature_config_vk.binarypb"], +} + +// "Updated" protobuf, used to validate forceFileRead(). +filegroup { + name: "gpuservice_unittest_feature_config_vk_force_read_prototext", + srcs: [ + "data/feature_config_test_force_read.txtpb", + ], +} + +genrule { + name: "gpuservice_unittest_feature_config_vk_force_read_binarypb", + defaults: ["gpuservice_unittest_feature_config_pb_defaults"], + srcs: [ + ":gpuservice_unittest_feature_config_vk_force_read_prototext", + ], + out: ["gpuservice_unittest_feature_config_vk_force_read.binarypb"], +} + cc_test { name: "gpuservice_unittest", test_suites: ["device-tests"], defaults: [ + "aconfig_lib_cc_static_link.defaults", "libgpuservice_defaults", ], srcs: [ + "FeatureOverrideParserTest.cpp", "GpuMemTest.cpp", "GpuMemTracerTest.cpp", - "GpuStatsTest.cpp", "GpuServiceTest.cpp", + "GpuStatsTest.cpp", ], header_libs: ["bpf_headers"], shared_libs: [ + "gpuservice_multiuser_flags_c_lib", "libbase", "libbinder", "libbpf_bcc", @@ -48,10 +103,15 @@ cc_test { "libutils", ], static_libs: [ + "gpuservice_unittest_flags_c_lib", "libgmock", "libgpuservice", "libperfetto_client_experimental", "perfetto_trace_protos", ], + data: [ + ":gpuservice_unittest_feature_config_vk_binarypb", + ":gpuservice_unittest_feature_config_vk_force_read_binarypb", + ], require_root: true, } diff --git a/services/gpuservice/tests/unittests/FeatureOverrideParserTest.cpp b/services/gpuservice/tests/unittests/FeatureOverrideParserTest.cpp new file mode 100644 index 0000000000..66556cd2d0 --- /dev/null +++ b/services/gpuservice/tests/unittests/FeatureOverrideParserTest.cpp @@ -0,0 +1,468 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#undef LOG_TAG +#define LOG_TAG "gpuservice_unittest" + +#include <android-base/file.h> +#include <log/log.h> +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +#include <com_android_graphics_graphicsenv_flags.h> +#include <feature_override/FeatureOverrideParser.h> + +using ::testing::AtLeast; +using ::testing::Return; + +namespace android { +namespace { + +std::string getTestBinarypbPath(const std::string &filename) { + std::string path = android::base::GetExecutableDirectory(); + path.append("/"); + path.append(filename); + + return path; +} + +class FeatureOverrideParserMock : public FeatureOverrideParser { +public: + MOCK_METHOD(std::string, getFeatureOverrideFilePath, (), (const, override)); +}; + +class FeatureOverrideParserTest : public testing::Test { +public: + FeatureOverrideParserTest() { + const ::testing::TestInfo *const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); + } + + ~FeatureOverrideParserTest() { + const ::testing::TestInfo *const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), + test_info->name()); + } + + void SetUp() override { + const std::string filename = "gpuservice_unittest_feature_config_vk.binarypb"; + + EXPECT_CALL(mFeatureOverrideParser, getFeatureOverrideFilePath()) + .WillRepeatedly(Return(getTestBinarypbPath(filename))); + } + + FeatureOverrideParserMock mFeatureOverrideParser; +}; + +testing::AssertionResult validateFeatureConfigTestTxtpbSizes(FeatureOverrides overrides) { + size_t expectedGlobalFeaturesSize = 3; + if (overrides.mGlobalFeatures.size() != expectedGlobalFeaturesSize) { + return testing::AssertionFailure() + << "overrides.mGlobalFeatures.size(): " << overrides.mGlobalFeatures.size() + << ", expected: " << expectedGlobalFeaturesSize; + } + + size_t expectedPackageFeaturesSize = 3; + if (overrides.mPackageFeatures.size() != expectedPackageFeaturesSize) { + return testing::AssertionFailure() + << "overrides.mPackageFeatures.size(): " << overrides.mPackageFeatures.size() + << ", expected: " << expectedPackageFeaturesSize; + } + + return testing::AssertionSuccess(); +} + +testing::AssertionResult validateFeatureConfigTestForceReadTxtpbSizes(FeatureOverrides overrides) { + size_t expectedGlobalFeaturesSize = 1; + if (overrides.mGlobalFeatures.size() != expectedGlobalFeaturesSize) { + return testing::AssertionFailure() + << "overrides.mGlobalFeatures.size(): " << overrides.mGlobalFeatures.size() + << ", expected: " << expectedGlobalFeaturesSize; + } + + size_t expectedPackageFeaturesSize = 0; + if (overrides.mPackageFeatures.size() != expectedPackageFeaturesSize) { + return testing::AssertionFailure() + << "overrides.mPackageFeatures.size(): " << overrides.mPackageFeatures.size() + << ", expected: " << expectedPackageFeaturesSize; + } + + return testing::AssertionSuccess(); +} + +testing::AssertionResult validateGlobalOverrides1(FeatureOverrides overrides) { + const int kTestFeatureIndex = 0; + const std::string expectedFeatureName = "globalOverrides1"; + const FeatureConfig &cfg = overrides.mGlobalFeatures[kTestFeatureIndex]; + + if (cfg.mFeatureName != expectedFeatureName) { + return testing::AssertionFailure() + << "cfg.mFeatureName: " << cfg.mFeatureName + << ", expected: " << expectedFeatureName; + } + + bool expectedEnabled = false; + if (cfg.mEnabled != expectedEnabled) { + return testing::AssertionFailure() + << "cfg.mEnabled: " << cfg.mEnabled + << ", expected: " << expectedEnabled; + } + + return testing::AssertionSuccess(); +} + +TEST_F(FeatureOverrideParserTest, globalOverrides1) { + FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); + + EXPECT_TRUE(validateFeatureConfigTestTxtpbSizes(overrides)); + EXPECT_TRUE(validateGlobalOverrides1(overrides)); +} + +testing::AssertionResult validateGlobalOverrides2(FeatureOverrides overrides) { + const int kTestFeatureIndex = 1; + const std::string expectedFeatureName = "globalOverrides2"; + const FeatureConfig &cfg = overrides.mGlobalFeatures[kTestFeatureIndex]; + + if (cfg.mFeatureName != expectedFeatureName) { + return testing::AssertionFailure() + << "cfg.mFeatureName: " << cfg.mFeatureName + << ", expected: " << expectedFeatureName; + } + + bool expectedEnabled = true; + if (cfg.mEnabled != expectedEnabled) { + return testing::AssertionFailure() + << "cfg.mEnabled: " << cfg.mEnabled + << ", expected: " << expectedEnabled; + } + + std::vector<uint32_t> expectedGpuVendorIDs = { + 0, // GpuVendorID::VENDOR_ID_TEST + 0x13B5, // GpuVendorID::VENDOR_ID_ARM + }; + if (cfg.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { + return testing::AssertionFailure() + << "cfg.mGpuVendorIDs.size(): " << cfg.mGpuVendorIDs.size() + << ", expected: " << expectedGpuVendorIDs.size(); + } + for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { + if (cfg.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { + std::stringstream msg; + msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg.mGpuVendorIDs[i] + << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; + return testing::AssertionFailure() << msg.str(); + } + } + + return testing::AssertionSuccess(); +} + +TEST_F(FeatureOverrideParserTest, globalOverrides2) { + FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); + + EXPECT_TRUE(validateGlobalOverrides2(overrides)); +} + +testing::AssertionResult validateGlobalOverrides3(FeatureOverrides overrides) { + const int kTestFeatureIndex = 2; + const std::string expectedFeatureName = "globalOverrides3"; + const FeatureConfig &cfg = overrides.mGlobalFeatures[kTestFeatureIndex]; + + if (cfg.mFeatureName != expectedFeatureName) { + return testing::AssertionFailure() + << "cfg.mFeatureName: " << cfg.mFeatureName + << ", expected: " << expectedFeatureName; + } + + bool expectedEnabled = true; + if (cfg.mEnabled != expectedEnabled) { + return testing::AssertionFailure() + << "cfg.mEnabled: " << cfg.mEnabled + << ", expected: " << expectedEnabled; + } + + std::vector<uint32_t> expectedGpuVendorIDs = { + 0, // GpuVendorID::VENDOR_ID_TEST + 0x8086, // GpuVendorID::VENDOR_ID_INTEL + }; + if (cfg.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { + return testing::AssertionFailure() + << "cfg.mGpuVendorIDs.size(): " << cfg.mGpuVendorIDs.size() + << ", expected: " << expectedGpuVendorIDs.size(); + } + for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { + if (cfg.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { + std::stringstream msg; + msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg.mGpuVendorIDs[i] + << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; + return testing::AssertionFailure() << msg.str(); + } + } + + return testing::AssertionSuccess(); +} + +TEST_F(FeatureOverrideParserTest, globalOverrides3) { +FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); + +EXPECT_TRUE(validateGlobalOverrides3(overrides)); +} + +testing::AssertionResult validatePackageOverrides1(FeatureOverrides overrides) { + const std::string expectedTestPackageName = "com.gpuservice_unittest.packageOverrides1"; + + if (!overrides.mPackageFeatures.count(expectedTestPackageName)) { + return testing::AssertionFailure() + << "overrides.mPackageFeatures missing expected package: " + << expectedTestPackageName; + } + + const std::vector<FeatureConfig>& features = + overrides.mPackageFeatures[expectedTestPackageName]; + + size_t expectedFeaturesSize = 1; + if (features.size() != expectedFeaturesSize) { + return testing::AssertionFailure() + << "features.size(): " << features.size() + << ", expectedFeaturesSize: " << expectedFeaturesSize; + } + + const std::string expectedFeatureName = "packageOverrides1"; + const FeatureConfig &cfg = features[0]; + + if (cfg.mFeatureName != expectedFeatureName) { + return testing::AssertionFailure() + << "cfg.mFeatureName: " << cfg.mFeatureName + << ", expected: " << expectedFeatureName; + } + + bool expectedEnabled = true; + if (cfg.mEnabled != expectedEnabled) { + return testing::AssertionFailure() + << "cfg.mEnabled: " << cfg.mEnabled + << ", expected: " << expectedEnabled; + } + + return testing::AssertionSuccess(); +} + +TEST_F(FeatureOverrideParserTest, packageOverrides1) { + FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); + + EXPECT_TRUE(validateFeatureConfigTestTxtpbSizes(overrides)); + EXPECT_TRUE(validatePackageOverrides1(overrides)); +} + +testing::AssertionResult validateForceFileRead(FeatureOverrides overrides) { + const int kTestFeatureIndex = 0; + const std::string expectedFeatureName = "forceFileRead"; + + const FeatureConfig &cfg = overrides.mGlobalFeatures[kTestFeatureIndex]; + if (cfg.mFeatureName != expectedFeatureName) { + return testing::AssertionFailure() + << "cfg.mFeatureName: " << cfg.mFeatureName + << ", expected: " << expectedFeatureName; + } + + bool expectedEnabled = false; + if (cfg.mEnabled != expectedEnabled) { + return testing::AssertionFailure() + << "cfg.mEnabled: " << cfg.mEnabled + << ", expected: " << expectedEnabled; + } + + return testing::AssertionSuccess(); +} + +testing::AssertionResult validatePackageOverrides2(FeatureOverrides overrides) { + const std::string expectedPackageName = "com.gpuservice_unittest.packageOverrides2"; + + if (!overrides.mPackageFeatures.count(expectedPackageName)) { + return testing::AssertionFailure() + << "overrides.mPackageFeatures missing expected package: " << expectedPackageName; + } + + const std::vector<FeatureConfig>& features = overrides.mPackageFeatures[expectedPackageName]; + + size_t expectedFeaturesSize = 1; + if (features.size() != expectedFeaturesSize) { + return testing::AssertionFailure() + << "features.size(): " << features.size() + << ", expectedFeaturesSize: " << expectedFeaturesSize; + } + + const std::string expectedFeatureName = "packageOverrides2"; + const FeatureConfig &cfg = features[0]; + + if (cfg.mFeatureName != expectedFeatureName) { + return testing::AssertionFailure() + << "cfg.mFeatureName: " << cfg.mFeatureName + << ", expected: " << expectedFeatureName; + } + + bool expectedEnabled = false; + if (cfg.mEnabled != expectedEnabled) { + return testing::AssertionFailure() + << "cfg.mEnabled: " << cfg.mEnabled + << ", expected: " << expectedEnabled; + } + + std::vector<uint32_t> expectedGpuVendorIDs = { + 0, // GpuVendorID::VENDOR_ID_TEST + 0x8086, // GpuVendorID::VENDOR_ID_INTEL + }; + if (cfg.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { + return testing::AssertionFailure() + << "cfg.mGpuVendorIDs.size(): " << cfg.mGpuVendorIDs.size() + << ", expected: " << expectedGpuVendorIDs.size(); + } + for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { + if (cfg.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { + std::stringstream msg; + msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg.mGpuVendorIDs[i] + << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; + return testing::AssertionFailure() << msg.str(); + } + } + + return testing::AssertionSuccess(); +} + +TEST_F(FeatureOverrideParserTest, packageOverrides2) { + FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); + + EXPECT_TRUE(validatePackageOverrides2(overrides)); +} + +testing::AssertionResult validatePackageOverrides3(FeatureOverrides overrides) { + const std::string expectedPackageName = "com.gpuservice_unittest.packageOverrides3"; + + if (!overrides.mPackageFeatures.count(expectedPackageName)) { + return testing::AssertionFailure() + << "overrides.mPackageFeatures missing expected package: " << expectedPackageName; + } + + const std::vector<FeatureConfig>& features = overrides.mPackageFeatures[expectedPackageName]; + + size_t expectedFeaturesSize = 2; + if (features.size() != expectedFeaturesSize) { + return testing::AssertionFailure() + << "features.size(): " << features.size() + << ", expectedFeaturesSize: " << expectedFeaturesSize; + } + + std::string expectedFeatureName = "packageOverrides3_1"; + const FeatureConfig &cfg_1 = features[0]; + + if (cfg_1.mFeatureName != expectedFeatureName) { + return testing::AssertionFailure() + << "cfg.mFeatureName: " << cfg_1.mFeatureName + << ", expected: " << expectedFeatureName; + } + + bool expectedEnabled = false; + if (cfg_1.mEnabled != expectedEnabled) { + return testing::AssertionFailure() + << "cfg.mEnabled: " << cfg_1.mEnabled + << ", expected: " << expectedEnabled; + } + + std::vector<uint32_t> expectedGpuVendorIDs = { + 0, // GpuVendorID::VENDOR_ID_TEST + 0x13B5, // GpuVendorID::VENDOR_ID_ARM + }; + if (cfg_1.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { + return testing::AssertionFailure() + << "cfg.mGpuVendorIDs.size(): " << cfg_1.mGpuVendorIDs.size() + << ", expected: " << expectedGpuVendorIDs.size(); + } + for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { + if (cfg_1.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { + std::stringstream msg; + msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg_1.mGpuVendorIDs[i] + << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; + return testing::AssertionFailure() << msg.str(); + } + } + + expectedFeatureName = "packageOverrides3_2"; + const FeatureConfig &cfg_2 = features[1]; + + if (cfg_2.mFeatureName != expectedFeatureName) { + return testing::AssertionFailure() + << "cfg.mFeatureName: " << cfg_2.mFeatureName + << ", expected: " << expectedFeatureName; + } + + expectedEnabled = true; + if (cfg_2.mEnabled != expectedEnabled) { + return testing::AssertionFailure() + << "cfg.mEnabled: " << cfg_2.mEnabled + << ", expected: " << expectedEnabled; + } + + expectedGpuVendorIDs = { + 0, // GpuVendorID::VENDOR_ID_TEST + 0x8086, // GpuVendorID::VENDOR_ID_INTEL + }; + if (cfg_2.mGpuVendorIDs.size() != expectedGpuVendorIDs.size()) { + return testing::AssertionFailure() + << "cfg.mGpuVendorIDs.size(): " << cfg_2.mGpuVendorIDs.size() + << ", expected: " << expectedGpuVendorIDs.size(); + } + for (int i = 0; i < expectedGpuVendorIDs.size(); i++) { + if (cfg_2.mGpuVendorIDs[i] != expectedGpuVendorIDs[i]) { + std::stringstream msg; + msg << "cfg.mGpuVendorIDs[" << i << "]: 0x" << std::hex << cfg_2.mGpuVendorIDs[i] + << ", expected: 0x" << std::hex << expectedGpuVendorIDs[i]; + return testing::AssertionFailure() << msg.str(); + } + } + + return testing::AssertionSuccess(); +} + +TEST_F(FeatureOverrideParserTest, packageOverrides3) { +FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); + +EXPECT_TRUE(validatePackageOverrides3(overrides)); +} + +TEST_F(FeatureOverrideParserTest, forceFileRead) { + FeatureOverrides overrides = mFeatureOverrideParser.getFeatureOverrides(); + + // Validate the "original" contents are present. + EXPECT_TRUE(validateFeatureConfigTestTxtpbSizes(overrides)); + EXPECT_TRUE(validateGlobalOverrides1(overrides)); + + // "Update" the config file. + const std::string filename = "gpuservice_unittest_feature_config_vk_force_read.binarypb"; + EXPECT_CALL(mFeatureOverrideParser, getFeatureOverrideFilePath()) + .WillRepeatedly(Return(getTestBinarypbPath(filename))); + + mFeatureOverrideParser.forceFileRead(); + + overrides = mFeatureOverrideParser.getFeatureOverrides(); + + // Validate the new file contents were read and parsed. + EXPECT_TRUE(validateFeatureConfigTestForceReadTxtpbSizes(overrides)); + EXPECT_TRUE(validateForceFileRead(overrides)); +} + +} // namespace +} // namespace android diff --git a/services/gpuservice/tests/unittests/data/feature_config_test.txtpb b/services/gpuservice/tests/unittests/data/feature_config_test.txtpb new file mode 100644 index 0000000000..44a6f78e84 --- /dev/null +++ b/services/gpuservice/tests/unittests/data/feature_config_test.txtpb @@ -0,0 +1,90 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Feature Configuration Test Data +# +# proto-file: services/gpuservice/feature_override/proto/feature_config.proto +# proto-message: FeatureOverrideProtos + +# The 'feature_name' entries correspond to the FeatureOverrideParserTest() unit test name. +global_features [ + { + feature_name: "globalOverrides1" + enabled: False + }, + { + feature_name: "globalOverrides2" + enabled: True + gpu_vendor_ids: [ + VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. + VENDOR_ID_ARM + ] + }, + { + feature_name: "globalOverrides3" + enabled: True + gpu_vendor_ids: [ + VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. + VENDOR_ID_INTEL + ] + } +] + +# The 'package_name' and 'feature_name' entries correspond to the +# FeatureOverrideParserTest() unit test name. +package_features [ + { + package_name: "com.gpuservice_unittest.packageOverrides1" + feature_configs: [ + { + feature_name: "packageOverrides1" + enabled: True + } + ] + }, + { + package_name: "com.gpuservice_unittest.packageOverrides2" + feature_configs: [ + { + feature_name: "packageOverrides2" + enabled: False + gpu_vendor_ids: [ + VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. + VENDOR_ID_INTEL + ] + } + ] + }, + { + package_name: "com.gpuservice_unittest.packageOverrides3" + feature_configs: [ + { + feature_name: "packageOverrides3_1" + enabled: False + gpu_vendor_ids: [ + VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. + VENDOR_ID_ARM + ] + }, + { + feature_name: "packageOverrides3_2" + enabled: True + gpu_vendor_ids: [ + VENDOR_ID_TEST, # Match every GPU Vendor ID, so the feature isn't dropped when parsed. + VENDOR_ID_INTEL + ] + } + ] + } +] diff --git a/services/gpuservice/tests/unittests/data/feature_config_test_force_read.txtpb b/services/gpuservice/tests/unittests/data/feature_config_test_force_read.txtpb new file mode 100644 index 0000000000..cf6a67e314 --- /dev/null +++ b/services/gpuservice/tests/unittests/data/feature_config_test_force_read.txtpb @@ -0,0 +1,26 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Feature Configuration Test Data +# +# proto-file: services/gpuservice/feature_override/proto/feature_config.proto +# proto-message: FeatureOverrideProtos + +# The 'feature_name' entries correspond to the FeatureOverrideParserTest() unit test name. +global_features [ + { + feature_name: "forceFileRead" + enabled: False + } +] diff --git a/services/gpuservice/vts/OWNERS b/services/gpuservice/vts/OWNERS index a63de1c306..13a089fc02 100644 --- a/services/gpuservice/vts/OWNERS +++ b/services/gpuservice/vts/OWNERS @@ -1,8 +1,5 @@ # Bug component: 653544 kocdemir@google.com paulthomson@google.com -pbaiget@google.com -lfy@google.com chrisforbes@google.com -lpy@google.com alecmouri@google.com diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp index ca92ab5aca..107fd207be 100644 --- a/services/inputflinger/Android.bp +++ b/services/inputflinger/Android.bp @@ -32,15 +32,15 @@ cc_defaults { host_supported: true, cpp_std: "c++20", cflags: [ + "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION", "-Wall", - "-Wextra", "-Werror", + "-Wextra", "-Wno-unused-parameter", - "-Wthread-safety", "-Wshadow", "-Wshadow-field-in-constructor-modified", "-Wshadow-uncaptured-local", - "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION", + "-Wthread-safety", ], sanitize: { misc_undefined: [ @@ -62,8 +62,8 @@ cc_defaults { memtag_heap: true, undefined: true, misc_undefined: [ - "bounds", "all", + "bounds", ], }, }, @@ -114,16 +114,16 @@ cc_defaults { "liblog", "libprotobuf-cpp-lite", "libstatslog", - "libutils", "libstatspull", "libstatssocket", + "libutils", "packagemanager_aidl-cpp", "server_configurable_flags", ], static_libs: [ "libattestation", - "libperfetto_client_experimental", "libpalmrejection", + "libperfetto_client_experimental", "libui-types", ], generated_headers: [ @@ -161,10 +161,10 @@ cc_library_shared { shared_libs: [ // This should consist only of dependencies from inputflinger. Other dependencies should be // in cc_defaults so that they are included in the tests. + "libPlatformProperties", "libinputflinger_base", "libinputreader", "libinputreporter", - "libPlatformProperties", ], static_libs: [ "libinputdispatcher", @@ -185,8 +185,8 @@ cc_library_headers { name: "libinputflinger_headers", host_supported: true, export_include_dirs: [ - "include", ".", + "include", ], header_libs: [ "libchrome-gestures_headers", @@ -247,49 +247,40 @@ cc_library_shared { phony { name: "checkinput", required: [ - // native targets - "libgui_test", - "libinput", - "libinputreader_static", - "libinputflinger", - "inputflinger_tests", - "inputflinger_benchmarks", - "libinput_tests", - "libpalmrejection_test", - "libandroid_runtime", - "libinputservice_test", "Bug-115739809", - "StructLayout_test", - - // jni - "libservices.core", - - // rust targets - "libinput_rust_test", - - // native fuzzers - "inputflinger_latencytracker_fuzzer", - "inputflinger_cursor_input_fuzzer", - "inputflinger_keyboard_input_fuzzer", - "inputflinger_multitouch_input_fuzzer", - "inputflinger_switch_input_fuzzer", - "inputflinger_touchpad_input_fuzzer", - "inputflinger_input_reader_fuzzer", - "inputflinger_blocking_queue_fuzzer", - "inputflinger_input_classifier_fuzzer", - "inputflinger_input_dispatcher_fuzzer", - - // Java/Kotlin targets - "CtsWindowManagerDeviceWindow", - "InputTests", "CtsHardwareTestCases", "CtsInputTestCases", + "CtsSecurityBulletinHostTestCases", + "CtsSecurityTestCases", "CtsViewTestCases", "CtsWidgetTestCases", + "CtsWindowManagerDeviceWindow", "FrameworksCoreTests", "FrameworksServicesTests", - "CtsSecurityTestCases", - "CtsSecurityBulletinHostTestCases", + "InputTests", + "StructLayout_test", + "inputflinger_benchmarks", + "inputflinger_blocking_queue_fuzzer", + "inputflinger_cursor_input_fuzzer", + "inputflinger_input_classifier_fuzzer", + "inputflinger_input_dispatcher_fuzzer", + "inputflinger_input_reader_fuzzer", + "inputflinger_keyboard_input_fuzzer", + "inputflinger_latencytracker_fuzzer", + "inputflinger_multitouch_input_fuzzer", + "inputflinger_switch_input_fuzzer", + "inputflinger_tests", + "inputflinger_touchpad_input_fuzzer", + "libandroid_runtime", + "libgui_test", + "libinput", + "libinput_rust_test", + "libinput_tests", + "libinputflinger", + "libinputreader_static", + "libinputservice_test", + "libpalmrejection_test", + "libservices.core", "monkey_test", ], } diff --git a/services/inputflinger/InputFilter.cpp b/services/inputflinger/InputFilter.cpp index 2ef94fbb07..bb4e617bde 100644 --- a/services/inputflinger/InputFilter.cpp +++ b/services/inputflinger/InputFilter.cpp @@ -56,7 +56,7 @@ InputFilter::InputFilter(InputListenerInterface& listener, IInputFlingerRust& ru void InputFilter::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) { mDeviceInfos.clear(); mDeviceInfos.reserve(args.inputDeviceInfos.size()); - for (auto info : args.inputDeviceInfos) { + for (const auto& info : args.inputDeviceInfos) { AidlDeviceInfo& aidlInfo = mDeviceInfos.emplace_back(); aidlInfo.deviceId = info.getId(); aidlInfo.external = info.isExternal(); diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp index b155122749..7d62ed9461 100644 --- a/services/inputflinger/InputManager.cpp +++ b/services/inputflinger/InputManager.cpp @@ -41,8 +41,6 @@ namespace { const bool ENABLE_INPUT_DEVICE_USAGE_METRICS = sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true); -const bool ENABLE_INPUT_FILTER_RUST = input_flags::enable_input_filter_rust_impl(); - int32_t exceptionCodeFromStatusT(status_t status) { switch (status) { case OK: @@ -134,12 +132,10 @@ InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy, mTracingStages.emplace_back( std::make_unique<TracedInputListener>("InputDispatcher", *mDispatcher)); - if (ENABLE_INPUT_FILTER_RUST) { - mInputFilter = std::make_unique<InputFilter>(*mTracingStages.back(), *mInputFlingerRust, - inputFilterPolicy); - mTracingStages.emplace_back( - std::make_unique<TracedInputListener>("InputFilter", *mInputFilter)); - } + mInputFilter = std::make_unique<InputFilter>(*mTracingStages.back(), *mInputFlingerRust, + inputFilterPolicy); + mTracingStages.emplace_back( + std::make_unique<TracedInputListener>("InputFilter", *mInputFilter)); if (ENABLE_INPUT_DEVICE_USAGE_METRICS) { mCollector = std::make_unique<InputDeviceMetricsCollector>(*mTracingStages.back()); @@ -250,10 +246,8 @@ void InputManager::dump(std::string& dump) { mCollector->dump(dump); dump += '\n'; } - if (ENABLE_INPUT_FILTER_RUST) { - mInputFilter->dump(dump); - dump += '\n'; - } + mInputFilter->dump(dump); + dump += '\n'; mDispatcher->dump(dump); dump += '\n'; } diff --git a/services/inputflinger/NotifyArgs.cpp b/services/inputflinger/NotifyArgs.cpp index b2680a2139..3de639f36c 100644 --- a/services/inputflinger/NotifyArgs.cpp +++ b/services/inputflinger/NotifyArgs.cpp @@ -206,4 +206,9 @@ const char* toString(const NotifyArgs& args) { return std::visit(toStringVisitor, args); } +std::ostream& operator<<(std::ostream& out, const NotifyArgs& args) { + out << toString(args); + return out; +} + } // namespace android diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp index 5bf6ebbb46..98f0f346df 100644 --- a/services/inputflinger/PointerChoreographer.cpp +++ b/services/inputflinger/PointerChoreographer.cpp @@ -17,10 +17,13 @@ #define LOG_TAG "PointerChoreographer" #include <android-base/logging.h> +#include <android/configuration.h> #include <com_android_input_flags.h> +#include <algorithm> #if defined(__ANDROID__) #include <gui/SurfaceComposerClient.h> #endif +#include <input/InputFlags.h> #include <input/Keyboard.h> #include <input/PrintTools.h> #include <unordered_set> @@ -28,42 +31,12 @@ #include "PointerChoreographer.h" #define INDENT " " +#define INDENT2 " " namespace android { namespace { -bool isFromMouse(const NotifyMotionArgs& args) { - return isFromSource(args.source, AINPUT_SOURCE_MOUSE) && - args.pointerProperties[0].toolType == ToolType::MOUSE; -} - -bool isFromTouchpad(const NotifyMotionArgs& args) { - return isFromSource(args.source, AINPUT_SOURCE_MOUSE) && - args.pointerProperties[0].toolType == ToolType::FINGER; -} - -bool isFromDrawingTablet(const NotifyMotionArgs& args) { - return isFromSource(args.source, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS) && - isStylusToolType(args.pointerProperties[0].toolType); -} - -bool isHoverAction(int32_t action) { - return action == AMOTION_EVENT_ACTION_HOVER_ENTER || - action == AMOTION_EVENT_ACTION_HOVER_MOVE || action == AMOTION_EVENT_ACTION_HOVER_EXIT; -} - -bool isStylusHoverEvent(const NotifyMotionArgs& args) { - return isStylusEvent(args.source, args.pointerProperties) && isHoverAction(args.action); -} - -bool isMouseOrTouchpad(uint32_t sources) { - // Check if this is a mouse or touchpad, but not a drawing tablet. - return isFromSource(sources, AINPUT_SOURCE_MOUSE_RELATIVE) || - (isFromSource(sources, AINPUT_SOURCE_MOUSE) && - !isFromSource(sources, AINPUT_SOURCE_STYLUS)); -} - inline void notifyPointerDisplayChange(std::optional<std::tuple<ui::LogicalDisplayId, vec2>> change, PointerChoreographerPolicyInterface& policy) { if (!change) { @@ -114,6 +87,17 @@ vec2 calculatePositionOnDestinationViewport(const DisplayViewport& destinationVi } } +// The standardised medium display density for which 1 px = 1 dp +constexpr int32_t DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM; + +inline float pxToDp(int px, int dpi) { + return static_cast<float>(px * DENSITY_MEDIUM) / static_cast<float>(dpi); +} + +inline int dpToPx(float dp, int dpi) { + return static_cast<int>((dp * dpi) / DENSITY_MEDIUM); +} + } // namespace // --- PointerChoreographer --- @@ -149,10 +133,11 @@ PointerChoreographer::PointerChoreographer( }), mNextListener(listener), mPolicy(policy), - mDefaultMouseDisplayId(ui::LogicalDisplayId::DEFAULT), + mCurrentMouseDisplayId(ui::LogicalDisplayId::INVALID), mNotifiedPointerDisplayId(ui::LogicalDisplayId::INVALID), mShowTouchesEnabled(false), mStylusPointerIconEnabled(false), + mPointerMotionFilterEnabled(false), mCurrentFocusedDisplay(ui::LogicalDisplayId::DEFAULT), mIsWindowInfoListenerRegistered(false), mWindowInfoListener(sp<PointerChoreographerDisplayInfoListener>::make(this)), @@ -224,15 +209,16 @@ NotifyMotionArgs PointerChoreographer::processMotion(const NotifyMotionArgs& arg PointerDisplayChange pointerDisplayChange; { // acquire lock std::scoped_lock _l(getLock()); - if (isFromMouse(args)) { + if (isFromMouse(args.source, args.pointerProperties[0].toolType)) { newArgs = processMouseEventLocked(args); pointerDisplayChange = calculatePointerDisplayChangeToNotify(); - } else if (isFromTouchpad(args)) { + } else if (isFromTouchpad(args.source, args.pointerProperties[0].toolType)) { newArgs = processTouchpadEventLocked(args); pointerDisplayChange = calculatePointerDisplayChangeToNotify(); - } else if (isFromDrawingTablet(args)) { + } else if (isFromDrawingTablet(args.source, args.pointerProperties[0].toolType)) { processDrawingTabletEventLocked(args); - } else if (mStylusPointerIconEnabled && isStylusHoverEvent(args)) { + } else if (mStylusPointerIconEnabled && + isStylusHoverEvent(args.source, args.pointerProperties, args.action)) { processStylusHoverEventLocked(args); } else if (isFromSource(args.source, AINPUT_SOURCE_TOUCHSCREEN)) { processTouchscreenAndStylusEventLocked(args); @@ -310,9 +296,11 @@ void PointerChoreographer::processPointerDeviceMotionEventLocked(NotifyMotionArg PointerControllerInterface& pc) { const float deltaX = newArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X); const float deltaY = newArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y); - - vec2 unconsumedDelta = pc.move(deltaX, deltaY); - if (com::android::input::flags::connected_displays_cursor() && + vec2 filteredDelta = + filterPointerMotionForAccessibilityLocked(pc.getPosition(), vec2{deltaX, deltaY}, + newArgs.displayId); + vec2 unconsumedDelta = pc.move(filteredDelta.x, filteredDelta.y); + if (InputFlags::connectedDisplaysCursorEnabled() && (std::abs(unconsumedDelta.x) > 0 || std::abs(unconsumedDelta.y) > 0)) { handleUnconsumedDeltaLocked(pc, unconsumedDelta); // pointer may have moved to a different viewport @@ -374,7 +362,7 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac LOG(FATAL) << "A cursor already exists on destination display" << destinationViewport.displayId; } - mDefaultMouseDisplayId = destinationViewport.displayId; + mCurrentMouseDisplayId = destinationViewport.displayId; auto pcNode = mMousePointersByDisplay.extract(sourceDisplayId); pcNode.key() = destinationViewport.displayId; mMousePointersByDisplay.insert(std::move(pcNode)); @@ -385,8 +373,7 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac pc.fade(PointerControllerInterface::Transition::IMMEDIATE); pc.setDisplayViewport(destinationViewport); vec2 destinationPosition = - calculatePositionOnDestinationViewport(destinationViewport, - cursorOffset - destinationOffset, + calculatePositionOnDestinationViewport(destinationViewport, destinationOffset, sourceBoundary); // Transform position back to un-rotated coordinate space before sending it to controller @@ -490,6 +477,14 @@ void PointerChoreographer::processStylusHoverEventLocked(const NotifyMotionArgs& << args.dump(); } + // Fade the mouse pointer on the display if there is one when the stylus starts hovering. + if (args.action == AMOTION_EVENT_ACTION_HOVER_ENTER) { + if (const auto it = mMousePointersByDisplay.find(args.displayId); + it != mMousePointersByDisplay.end()) { + it->second->fade(PointerControllerInterface::Transition::GRADUAL); + } + } + // Get the stylus pointer controller for the device, or create one if it doesn't exist. auto [it, controllerAdded] = mStylusPointersByDevice.try_emplace(args.deviceId, @@ -541,9 +536,6 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args) } void PointerChoreographer::onControllerAddedOrRemovedLocked() { - if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows()) { - return; - } bool requireListener = !mTouchPointersByDevice.empty() || !mMousePointersByDisplay.empty() || !mDrawingTabletPointersByDevice.empty() || !mStylusPointersByDevice.empty(); @@ -608,15 +600,21 @@ void PointerChoreographer::notifyPointerCaptureChanged( } void PointerChoreographer::setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) { - std::scoped_lock _l(getLock()); - mTopology = displayTopologyGraph; + PointerDisplayChange pointerDisplayChange; + { // acquire lock + std::scoped_lock _l(getLock()); + mTopology = displayTopologyGraph; + + // make primary display default mouse display, if it was not set or + // the existing display was removed + if (mCurrentMouseDisplayId == ui::LogicalDisplayId::INVALID || + mTopology.graph.find(mCurrentMouseDisplayId) == mTopology.graph.end()) { + mCurrentMouseDisplayId = mTopology.primaryDisplayId; + pointerDisplayChange = updatePointerControllersLocked(); + } + } // release lock - // make primary display default mouse display, if it was not set - // or the existing display was removed - if (mDefaultMouseDisplayId == ui::LogicalDisplayId::INVALID || - mTopology.graph.find(mDefaultMouseDisplayId) != mTopology.graph.end()) { - mDefaultMouseDisplayId = mTopology.primaryDisplayId; - } + notifyPointerDisplayChange(pointerDisplayChange, mPolicy); } void PointerChoreographer::dump(std::string& dump) { @@ -627,6 +625,8 @@ void PointerChoreographer::dump(std::string& dump) { mShowTouchesEnabled ? "true" : "false"); dump += StringPrintf(INDENT "Stylus PointerIcon Enabled: %s\n", mStylusPointerIconEnabled ? "true" : "false"); + dump += StringPrintf(INDENT "Accessibility Pointer Motion Filter Enabled: %s\n", + mPointerMotionFilterEnabled ? "true" : "false"); dump += INDENT "MousePointerControllers:\n"; for (const auto& [displayId, mousePointerController] : mMousePointersByDisplay) { @@ -648,6 +648,8 @@ void PointerChoreographer::dump(std::string& dump) { std::string pointerControllerDump = addLinePrefix(drawingTabletController->dump(), INDENT); dump += INDENT + std::to_string(deviceId) + " : " + pointerControllerDump; } + dump += INDENT "DisplayTopologyGraph:\n"; + dump += addLinePrefix(mTopology.dump(), INDENT2); dump += "\n"; } @@ -663,7 +665,25 @@ const DisplayViewport* PointerChoreographer::findViewportByIdLocked( ui::LogicalDisplayId PointerChoreographer::getTargetMouseDisplayLocked( ui::LogicalDisplayId associatedDisplayId) const { - return associatedDisplayId.isValid() ? associatedDisplayId : mDefaultMouseDisplayId; + if (!InputFlags::connectedDisplaysCursorAndAssociatedDisplayCursorBugfixEnabled()) { + if (associatedDisplayId.isValid()) { + return associatedDisplayId; + } + return mCurrentMouseDisplayId.isValid() ? mCurrentMouseDisplayId + : ui::LogicalDisplayId::DEFAULT; + } + // Associated display is not included in the topology, return this associated display. + if (associatedDisplayId.isValid() && + mTopology.graph.find(associatedDisplayId) == mTopology.graph.end()) { + return associatedDisplayId; + } + if (mCurrentMouseDisplayId.isValid()) { + return mCurrentMouseDisplayId; + } + if (mTopology.primaryDisplayId.isValid()) { + return mTopology.primaryDisplayId; + } + return ui::LogicalDisplayId::DEFAULT; } std::pair<ui::LogicalDisplayId, PointerControllerInterface&> @@ -772,7 +792,8 @@ PointerChoreographer::PointerDisplayChange PointerChoreographer::calculatePointerDisplayChangeToNotify() { ui::LogicalDisplayId displayIdToNotify = ui::LogicalDisplayId::INVALID; vec2 cursorPosition = {0, 0}; - if (const auto it = mMousePointersByDisplay.find(mDefaultMouseDisplayId); + if (const auto it = + mMousePointersByDisplay.find(getTargetMouseDisplayLocked(mCurrentMouseDisplayId)); it != mMousePointersByDisplay.end()) { const auto& pointerController = it->second; // Use the displayId from the pointerController, because it accurately reflects whether @@ -789,12 +810,16 @@ PointerChoreographer::calculatePointerDisplayChangeToNotify() { } void PointerChoreographer::setDefaultMouseDisplayId(ui::LogicalDisplayId displayId) { + if (InputFlags::connectedDisplaysCursorEnabled()) { + // In connected displays scenario, default mouse display will only be updated from topology. + return; + } PointerDisplayChange pointerDisplayChange; { // acquire lock std::scoped_lock _l(getLock()); - mDefaultMouseDisplayId = displayId; + mCurrentMouseDisplayId = displayId; pointerDisplayChange = updatePointerControllersLocked(); } // release lock @@ -962,6 +987,11 @@ void PointerChoreographer::setFocusedDisplay(ui::LogicalDisplayId displayId) { mCurrentFocusedDisplay = displayId; } +void PointerChoreographer::setAccessibilityPointerMotionFilterEnabled(bool enabled) { + std::scoped_lock _l(getLock()); + mPointerMotionFilterEnabled = enabled; +} + PointerChoreographer::ControllerConstructor PointerChoreographer::getMouseControllerConstructor( ui::LogicalDisplayId displayId) { std::function<std::shared_ptr<PointerControllerInterface>()> ctor = @@ -990,10 +1020,10 @@ PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusContr return ConstructorDelegate(std::move(ctor)); } -std::optional<std::pair<const DisplayViewport*, float /*offset*/>> +std::optional<std::pair<const DisplayViewport*, float /*offsetPx*/>> PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId sourceDisplayId, const DisplayTopologyPosition sourceBoundary, - float cursorOffset) const { + int32_t sourceCursorOffsetPx) const { const auto& sourceNode = mTopology.graph.find(sourceDisplayId); if (sourceNode == mTopology.graph.end()) { // Topology is likely out of sync with viewport info, wait for it to be updated @@ -1004,27 +1034,52 @@ PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId so if (adjacentDisplay.position != sourceBoundary) { continue; } - const DisplayViewport* destinationViewport = - findViewportByIdLocked(adjacentDisplay.displayId); - if (destinationViewport == nullptr) { + const DisplayViewport* adjacentViewport = findViewportByIdLocked(adjacentDisplay.displayId); + if (adjacentViewport == nullptr) { // Topology is likely out of sync with viewport info, wait for them to be updated LOG(WARNING) << "Cannot find viewport for adjacent display " << adjacentDisplay.displayId << "of source display " << sourceDisplayId; continue; } - // target position must be within target display boundary - const int32_t edgeSize = sourceBoundary == DisplayTopologyPosition::TOP || + // As displays can have different densities we need to do all calculations in + // density-independent-pixels a.k.a. dp values. + const int sourceDensity = mTopology.displaysDensity.at(sourceDisplayId); + const int adjacentDisplayDensity = mTopology.displaysDensity.at(adjacentDisplay.displayId); + const float sourceCursorOffsetDp = pxToDp(sourceCursorOffsetPx, sourceDensity); + const int32_t edgeSizePx = sourceBoundary == DisplayTopologyPosition::TOP || sourceBoundary == DisplayTopologyPosition::BOTTOM - ? (destinationViewport->logicalRight - destinationViewport->logicalLeft) - : (destinationViewport->logicalBottom - destinationViewport->logicalTop); - if (cursorOffset >= adjacentDisplay.offsetPx && - cursorOffset <= adjacentDisplay.offsetPx + edgeSize) { - return std::make_pair(destinationViewport, adjacentDisplay.offsetPx); + ? (adjacentViewport->logicalRight - adjacentViewport->logicalLeft) + : (adjacentViewport->logicalBottom - adjacentViewport->logicalTop); + const float adjacentEdgeSizeDp = pxToDp(edgeSizePx, adjacentDisplayDensity); + // Target position must be within target display boundary. + // Cursor should also be able to cross displays when only display corners are touching and + // there may be zero overlapping pixels. To accommodate this we have margin of one pixel + // around the end of the overlapping edge. + if (sourceCursorOffsetDp >= adjacentDisplay.offsetDp && + sourceCursorOffsetDp <= adjacentDisplay.offsetDp + adjacentEdgeSizeDp) { + const int destinationOffsetPx = + dpToPx(sourceCursorOffsetDp - adjacentDisplay.offsetDp, adjacentDisplayDensity); + return std::make_pair(adjacentViewport, destinationOffsetPx); } } return std::nullopt; } +vec2 PointerChoreographer::filterPointerMotionForAccessibilityLocked( + const vec2& current, const vec2& delta, const ui::LogicalDisplayId& displayId) { + if (!mPointerMotionFilterEnabled) { + return delta; + } + std::optional<vec2> filterResult = + mPolicy.filterPointerMotionForAccessibility(current, delta, displayId); + if (!filterResult.has_value()) { + // Disable filter when there's any error. + mPointerMotionFilterEnabled = false; + return delta; + } + return *filterResult; +} + // --- PointerChoreographer::PointerChoreographerDisplayInfoListener --- void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfosChanged( diff --git a/services/inputflinger/PointerChoreographer.h b/services/inputflinger/PointerChoreographer.h index c2f5ec0e87..67bdca1bab 100644 --- a/services/inputflinger/PointerChoreographer.h +++ b/services/inputflinger/PointerChoreographer.h @@ -90,6 +90,11 @@ public: * This method may be called on any thread (usually by the input manager on a binder thread). */ virtual void dump(std::string& dump) = 0; + + /** + * Enables motion event filter before pointer coordinates are determined. + */ + virtual void setAccessibilityPointerMotionFilterEnabled(bool enabled) = 0; }; class PointerChoreographer : public PointerChoreographerInterface { @@ -110,6 +115,7 @@ public: void setPointerIconVisibility(ui::LogicalDisplayId displayId, bool visible) override; void setFocusedDisplay(ui::LogicalDisplayId displayId) override; void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph); + void setAccessibilityPointerMotionFilterEnabled(bool enabled) override; void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override; void notifyKey(const NotifyKeyArgs& args) override; @@ -163,9 +169,13 @@ private: void handleUnconsumedDeltaLocked(PointerControllerInterface& pc, const vec2& unconsumedDelta) REQUIRES(getLock()); - std::optional<std::pair<const DisplayViewport*, float /*offset*/>> findDestinationDisplayLocked( - const ui::LogicalDisplayId sourceDisplayId, - const DisplayTopologyPosition sourceBoundary, float cursorOffset) const + std::optional<std::pair<const DisplayViewport*, float /*offsetPx*/>> + findDestinationDisplayLocked(const ui::LogicalDisplayId sourceDisplayId, + const DisplayTopologyPosition sourceBoundary, + int32_t sourceCursorOffsetPx) const REQUIRES(getLock()); + + vec2 filterPointerMotionForAccessibilityLocked(const vec2& current, const vec2& delta, + const ui::LogicalDisplayId& displayId) REQUIRES(getLock()); /* Topology is initialized with default-constructed value, which is an empty topology. Till we @@ -221,13 +231,19 @@ private: std::map<DeviceId, std::shared_ptr<PointerControllerInterface>> mDrawingTabletPointersByDevice GUARDED_BY(getLock()); - ui::LogicalDisplayId mDefaultMouseDisplayId GUARDED_BY(getLock()); + // In connected displays scenario, this tracks the latest display the cursor is at, within the + // DisplayTopology. By default, this will be set to topology primary display, and updated when + // mouse crossed to another display. + // In non-connected displays scenario, this will be treated as the default display cursor + // will be on, when mouse doesn't have associated display. + ui::LogicalDisplayId mCurrentMouseDisplayId GUARDED_BY(getLock()); ui::LogicalDisplayId mNotifiedPointerDisplayId GUARDED_BY(getLock()); std::vector<InputDeviceInfo> mInputDeviceInfos GUARDED_BY(getLock()); std::set<DeviceId> mMouseDevices GUARDED_BY(getLock()); std::vector<DisplayViewport> mViewports GUARDED_BY(getLock()); bool mShowTouchesEnabled GUARDED_BY(getLock()); bool mStylusPointerIconEnabled GUARDED_BY(getLock()); + bool mPointerMotionFilterEnabled GUARDED_BY(getLock()); std::set<ui::LogicalDisplayId /*displayId*/> mDisplaysWithPointersHidden; ui::LogicalDisplayId mCurrentFocusedDisplay GUARDED_BY(getLock()); diff --git a/services/inputflinger/PreferStylusOverTouchBlocker.cpp b/services/inputflinger/PreferStylusOverTouchBlocker.cpp index d9d0450148..6864947615 100644 --- a/services/inputflinger/PreferStylusOverTouchBlocker.cpp +++ b/services/inputflinger/PreferStylusOverTouchBlocker.cpp @@ -216,10 +216,10 @@ static std::string dumpArgs(const NotifyMotionArgs& args) { std::string PreferStylusOverTouchBlocker::dump() const { std::string out; - out += "mActiveStyli: " + dumpSet(mActiveStyli) + "\n"; + out += "mActiveStyli: " + dumpContainer(mActiveStyli) + "\n"; out += "mLastTouchEvents: " + dumpMap(mLastTouchEvents, constToString, dumpArgs) + "\n"; - out += "mDevicesWithMixedToolType: " + dumpSet(mDevicesWithMixedToolType) + "\n"; - out += "mCanceledDevices: " + dumpSet(mCanceledDevices) + "\n"; + out += "mDevicesWithMixedToolType: " + dumpContainer(mDevicesWithMixedToolType) + "\n"; + out += "mCanceledDevices: " + dumpContainer(mCanceledDevices) + "\n"; return out; } diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp index 0e9ec914b7..29de635a40 100644 --- a/services/inputflinger/UnwantedInteractionBlocker.cpp +++ b/services/inputflinger/UnwantedInteractionBlocker.cpp @@ -727,7 +727,7 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs if (!std::includes(oldSuppressedIds.begin(), oldSuppressedIds.end(), mSuppressedPointerIds.begin(), mSuppressedPointerIds.end())) { ALOGI("Palm detected, removing pointer ids %s after %" PRId64 "ms from %s", - dumpSet(mSuppressedPointerIds).c_str(), ns2ms(args.eventTime - args.downTime), + dumpContainer(mSuppressedPointerIds).c_str(), ns2ms(args.eventTime - args.downTime), args.dump().c_str()); } @@ -748,7 +748,7 @@ std::string PalmRejector::dump() const { out += "mSlotState:\n"; out += addLinePrefix(mSlotState.dump(), " "); out += "mSuppressedPointerIds: "; - out += dumpSet(mSuppressedPointerIds) + "\n"; + out += dumpContainer(mSuppressedPointerIds) + "\n"; std::stringstream state; state << *mSharedPalmState; out += "mSharedPalmState: " + state.str() + "\n"; diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp index 8b2b8432c3..1aa8b2b69b 100644 --- a/services/inputflinger/dispatcher/Android.bp +++ b/services/inputflinger/dispatcher/Android.bp @@ -49,8 +49,8 @@ filegroup { "LatencyAggregatorWithHistograms.cpp", "LatencyTracker.cpp", "Monitor.cpp", - "TouchedWindow.cpp", "TouchState.cpp", + "TouchedWindow.cpp", "trace/*.cpp", ], } @@ -71,9 +71,9 @@ cc_defaults { "liblog", "libprotobuf-cpp-lite", "libstatslog", - "libutils", "libstatspull", "libstatssocket", + "libutils", "packagemanager_aidl-cpp", "server_configurable_flags", ], diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 0b1e849bc7..888fcfb592 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -32,6 +32,7 @@ #include <gui/SurfaceComposerClient.h> #endif #include <input/InputDevice.h> +#include <input/InputFlags.h> #include <input/PrintTools.h> #include <input/TraceTools.h> #include <openssl/mem.h> @@ -418,7 +419,7 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato if (inputTarget.useDefaultPointerTransform() && !zeroCoords) { const ui::Transform& transform = inputTarget.getDefaultPointerTransform(); return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform, - inputTarget.displayTransform, + inputTarget.rawTransform, inputTarget.globalScaleFactor, uid, vsyncId, windowId); } @@ -439,7 +440,7 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato transform = &inputTarget.getTransformForPointer(firstMarkedBit(inputTarget.getPointerIds())); const ui::Transform inverseTransform = transform->inverse(); - displayTransform = &inputTarget.displayTransform; + displayTransform = &inputTarget.rawTransform; // Iterate through all pointers in the event to normalize against the first. for (size_t i = 0; i < motionEntry.getPointerCount(); i++) { @@ -788,52 +789,14 @@ void filterUntrustedTargets(TouchState& touchState, std::vector<InputTarget>& ta }); } -/** - * In general, touch should be always split between windows. Some exceptions: - * 1. Don't split touch if all of the below is true: - * (a) we have an active pointer down *and* - * (b) a new pointer is going down that's from the same device *and* - * (c) the window that's receiving the current pointer does not support split touch. - * 2. Don't split mouse events - */ -bool shouldSplitTouch(const TouchState& touchState, const MotionEntry& entry) { - if (isFromSource(entry.source, AINPUT_SOURCE_MOUSE)) { - // We should never split mouse events - return false; - } - for (const TouchedWindow& touchedWindow : touchState.windows) { - if (touchedWindow.windowHandle->getInfo()->isSpy()) { - // Spy windows should not affect whether or not touch is split. - continue; - } - if (touchedWindow.windowHandle->getInfo()->supportsSplitTouch()) { - continue; - } - if (touchedWindow.windowHandle->getInfo()->inputConfig.test( - gui::WindowInfo::InputConfig::IS_WALLPAPER)) { - // Wallpaper window should not affect whether or not touch is split - continue; - } - - if (touchedWindow.hasTouchingPointers(entry.deviceId)) { - return false; - } - } - return true; -} - -/** - * Return true if stylus is currently down anywhere on the specified display, and false otherwise. - */ -bool isStylusActiveInDisplay(ui::LogicalDisplayId displayId, - const std::unordered_map<ui::LogicalDisplayId /*displayId*/, - TouchState>& touchStatesByDisplay) { - const auto it = touchStatesByDisplay.find(displayId); - if (it == touchStatesByDisplay.end()) { - return false; - } - const TouchState& state = it->second; - return state.hasActiveStylus(); +bool shouldSplitTouch(int32_t source) { + // We should never split mouse events. This is because the events that are produced by touchpad + // are sent to InputDispatcher as two fingers (for example, pinch zoom), but they need to be + // dispatched to the same window. In those cases, the behaviour is also slightly different from + // default because the events should be sent to the cursor position rather than the x,y values + // of each of the fingers. + // The "normal" (uncaptured) events produced by touchpad and by mouse have SOURCE_MOUSE. + return !isFromSource(source, AINPUT_SOURCE_MOUSE); } Result<void> validateWindowInfosUpdate(const gui::WindowInfosUpdate& update) { @@ -929,7 +892,7 @@ InputTarget createInputTarget(const std::shared_ptr<Connection>& connection, const sp<android::gui::WindowInfoHandle>& windowHandle, InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags, - const ui::Transform& displayTransform, + const ui::Transform& rawTransform, std::optional<nsecs_t> firstDownTimeInTarget) { LOG_ALWAYS_FATAL_IF(connection == nullptr); InputTarget inputTarget{connection}; @@ -937,11 +900,26 @@ InputTarget createInputTarget(const std::shared_ptr<Connection>& connection, inputTarget.dispatchMode = dispatchMode; inputTarget.flags = targetFlags; inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor; - inputTarget.displayTransform = displayTransform; + inputTarget.rawTransform = rawTransform; inputTarget.firstDownTimeInTarget = firstDownTimeInTarget; return inputTarget; } +std::string dumpWindowForTouchOcclusion(const WindowInfo& info, bool isTouchedWindow) { + return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, " + "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32 + "], touchableRegion=%s, window={%s}, inputConfig={%s}, " + "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n", + isTouchedWindow ? "[TOUCHED] " : "", info.packageName.c_str(), + info.ownerUid.toString().c_str(), info.id, + toString(info.touchOcclusionMode).c_str(), info.alpha, info.frame.left, + info.frame.top, info.frame.right, info.frame.bottom, + dumpRegion(info.touchableRegion).c_str(), info.name.c_str(), + info.inputConfig.string().c_str(), toString(info.token != nullptr), + info.applicationInfo.name.c_str(), + binderToString(info.applicationInfo.token).c_str()); +} + } // namespace // --- InputDispatcher --- @@ -952,16 +930,18 @@ InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy) InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy, std::unique_ptr<trace::InputTracingBackendInterface> traceBackend) : mPolicy(policy), + mLooper(sp<Looper>::make(false)), mPendingEvent(nullptr), mLastDropReason(DropReason::NOT_DROPPED), mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER), mMinTimeBetweenUserActivityPokes(DEFAULT_USER_ACTIVITY_POKE_INTERVAL), + mConnectionManager(mLooper), + mTouchStates(mWindowInfos, mConnectionManager), mNextUnblockedEvent(nullptr), mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT), mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false), - mMaximumObscuringOpacityForTouch(1.0f), mFocusedDisplayId(ui::LogicalDisplayId::DEFAULT), mWindowTokenWithPointerCapture(nullptr), mAwaitedApplicationDisplayId(ui::LogicalDisplayId::INVALID), @@ -972,7 +952,6 @@ InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy, : std::move(std::unique_ptr<InputEventTimelineProcessor>( new LatencyAggregator()))), mLatencyTracker(*mInputEventTimelineProcessor) { - mLooper = sp<Looper>::make(false); mReporter = createInputReporter(); mWindowInfoListener = sp<DispatcherWindowListener>::make(*this); @@ -994,12 +973,10 @@ InputDispatcher::~InputDispatcher() { resetKeyRepeatLocked(); releasePendingEventLocked(); drainInboundQueueLocked(); +#if defined(__ANDROID__) + SurfaceComposerClient::getDefault()->removeWindowInfosListener(mWindowInfoListener); +#endif mCommandQueue.clear(); - - while (!mConnectionsByToken.empty()) { - std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second; - removeInputChannelLocked(connection->getToken(), /*notify=*/false); - } } status_t InputDispatcher::start() { @@ -1116,9 +1093,13 @@ nsecs_t InputDispatcher::processAnrsLocked() { } // If we reached here, we have an unresponsive connection. - std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken()); + std::shared_ptr<Connection> connection = + mConnectionManager.getConnection(mAnrTracker.firstToken()); if (connection == nullptr) { ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout()); + // As we no longer have entry for this connection, remove it form Anr tracker to prevent + // samme error being logged multiple times. + mAnrTracker.eraseToken(mAnrTracker.firstToken()); return nextAnrCheck; } connection->responsive = false; @@ -1165,9 +1146,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t& nextWakeupTime) { // If dispatching is frozen, do not process timeouts or try to deliver any new events. if (mDispatchFrozen) { - if (DEBUG_FOCUS) { - ALOGD("Dispatch frozen. Waiting some more."); - } + LOG_IF(INFO, DEBUG_FOCUS) << "Dispatch frozen. Waiting some more."; return; } @@ -1277,13 +1256,9 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t& nextWakeupTime) { if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) { // The event is stale. However, only drop stale events if there isn't an ongoing // gesture. That would allow us to complete the processing of the current stroke. - const auto touchStateIt = mTouchStatesByDisplay.find(motionEntry->displayId); - if (touchStateIt != mTouchStatesByDisplay.end()) { - const TouchState& touchState = touchStateIt->second; - if (!touchState.hasTouchingPointers(motionEntry->deviceId) && - !touchState.hasHoveringPointers(motionEntry->deviceId)) { - dropReason = DropReason::STALE; - } + if (!mTouchStates.hasTouchingOrHoveringPointers(motionEntry->displayId, + motionEntry->deviceId)) { + dropReason = DropReason::STALE; } } if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) { @@ -1364,11 +1339,11 @@ bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEnt // Alternatively, maybe there's a spy window that could handle this event. const std::vector<sp<WindowInfoHandle>> touchedSpies = - mWindowInfos.findTouchedSpyWindowsAt(displayId, x, y, isStylus, - motionEntry.deviceId, mTouchStatesByDisplay); + findTouchedSpyWindowsAt(displayId, x, y, isStylus, motionEntry.deviceId, + mWindowInfos); for (const auto& windowHandle : touchedSpies) { const std::shared_ptr<Connection> connection = - getConnectionLocked(windowHandle->getToken()); + mConnectionManager.getConnection(windowHandle->getToken()); if (connection != nullptr && connection->responsive) { // This spy window could take more input. Drop all events preceding this // event, so that the spy window can get a chance to receive the stream. @@ -1490,9 +1465,9 @@ sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findTouchedWindowAt( return nullptr; } -std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked( - ui::LogicalDisplayId displayId, const sp<WindowInfoHandle>& touchedWindow, - int32_t pointerId) const { +std::vector<InputTarget> InputDispatcher::DispatcherTouchState::findOutsideTargets( + ui::LogicalDisplayId displayId, const sp<gui::WindowInfoHandle>& touchedWindow, + int32_t pointerId, std::function<void()> dump) { if (touchedWindow == nullptr) { return {}; } @@ -1510,38 +1485,27 @@ std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked( if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) { std::bitset<MAX_POINTER_ID + 1> pointerIds; pointerIds.set(pointerId); - addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::OUTSIDE, - ftl::Flags<InputTarget::Flags>(), pointerIds, - /*firstDownTimeInTarget=*/std::nullopt, outsideTargets); + addPointerWindowTarget(windowHandle, InputTarget::DispatchMode::OUTSIDE, + ftl::Flags<InputTarget::Flags>(), pointerIds, + /*firstDownTimeInTarget=*/std::nullopt, + /*pointerDisplayId=*/std::nullopt, dump, outsideTargets); } } return outsideTargets; } -std::vector<sp<WindowInfoHandle>> InputDispatcher::DispatcherWindowInfo::findTouchedSpyWindowsAt( +std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAt( ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId, - const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) const { + const DispatcherWindowInfo& windowInfos) { // Traverse windows from front to back and gather the touched spy windows. std::vector<sp<WindowInfoHandle>> spyWindows; - const auto& windowHandles = getWindowHandlesForDisplay(displayId); + const ui::Transform displayTransform = windowInfos.getDisplayTransform(displayId); + const auto& windowHandles = windowInfos.getWindowHandlesForDisplay(displayId); for (const sp<WindowInfoHandle>& windowHandle : windowHandles) { const WindowInfo& info = *windowHandle->getInfo(); - if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, - getDisplayTransform(displayId))) { - // Generally, we would skip any pointer that's outside of the window. However, if the - // spy prevents splitting, and already has some of the pointers from this device, then - // it should get more pointers from the same device, even if they are outside of that - // window - if (info.supportsSplitTouch()) { - continue; - } - - // We know that split touch is not supported. Skip this window only if it doesn't have - // any touching pointers for this device already. - if (!windowHasTouchingPointers(windowHandle, deviceId, touchStatesByDisplay)) { - continue; - } - // If it already has pointers down for this device, then give it this pointer, too. + if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, displayTransform)) { + // Skip if the pointer is outside of the window. + continue; } if (!info.isSpy()) { // The first touched non-spy window was found, so return the spy windows touched so far. @@ -1556,9 +1520,7 @@ void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason const char* reason; switch (dropReason) { case DropReason::POLICY: - if (debugInboundEventDetails()) { - ALOGD("Dropped event because policy consumed it."); - } + LOG_IF(INFO, debugInboundEventDetails()) << "Dropped event because policy consumed it."; reason = "inbound event was dropped because the policy consumed it"; break; case DropReason::DISABLED: @@ -1672,9 +1634,7 @@ void InputDispatcher::releasePendingEventLocked() { void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry) { const std::shared_ptr<InjectionState>& injectionState = entry->injectionState; if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) { - if (DEBUG_DISPATCH_CYCLE) { - ALOGD("Injected inbound event was dropped."); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) << "Injected inbound event was dropped."; setInjectionResult(*entry, InputEventInjectionResult::FAILED); } if (entry == mNextUnblockedEvent) { @@ -1714,10 +1674,9 @@ std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t cur bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, const DeviceResetEntry& entry) { - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime, - entry.deviceId); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "dispatchDeviceReset - eventTime=" << entry.eventTime + << ", deviceId=" << entry.deviceId; // Reset key repeating in case a keyboard device was disabled or enabled. if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) { @@ -1731,9 +1690,7 @@ bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, synthesizeCancelationEventsForAllConnectionsLocked(options); // Remove all active pointers from this device - for (auto& [_, touchState] : mTouchStatesByDisplay) { - touchState.removeAllPointersForDevice(entry.deviceId); - } + mTouchStates.removeAllPointersForDevice(entry.deviceId); return true; } @@ -1763,7 +1720,8 @@ void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bo void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<const FocusEntry> entry) { - std::shared_ptr<Connection> connection = getConnectionLocked(entry->connectionToken); + std::shared_ptr<Connection> connection = + mConnectionManager.getConnection(entry->connectionToken); if (connection == nullptr) { return; // Connection has gone away } @@ -1831,7 +1789,7 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked( } } - auto connection = getConnectionLocked(token); + auto connection = mConnectionManager.getConnection(token); if (connection == nullptr) { // Window has gone away, clean up Pointer Capture state. mWindowTokenWithPointerCapture = nullptr; @@ -1870,7 +1828,7 @@ std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked if (token == nullptr) { continue; } - std::shared_ptr<Connection> connection = getConnectionLocked(token); + std::shared_ptr<Connection> connection = mConnectionManager.getConnection(token); if (connection == nullptr) { continue; // Connection has gone away } @@ -1910,9 +1868,8 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) { // The key on device 'deviceId' is still down, do not stop key repeat - if (debugInboundEventDetails()) { - ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId); - } + LOG_IF(INFO, debugInboundEventDetails()) + << "deviceId=" << entry->deviceId << " got KEY_UP as stale"; } else if (!entry->syntheticRepeat) { resetKeyRepeatLocked(); } @@ -2009,25 +1966,24 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con } void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) { - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%s, " - "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, " - "metaState=0x%x, repeatCount=%d, downTime=%" PRId64, - prefix, entry.eventTime, entry.deviceId, entry.source, - entry.displayId.toString().c_str(), entry.policyFlags, entry.action, entry.flags, - entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount, entry.downTime); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << prefix << "eventTime=" << entry.eventTime << ", deviceId=" << entry.deviceId + << ", source=0x" << std::hex << entry.source + << ", displayId=" << entry.displayId.toString() << ", policyFlags=0x" + << entry.policyFlags << ", action=0x" << entry.action << ", flags=0x" << entry.flags + << ", keyCode=0x" << entry.keyCode << ", scanCode=0x" << entry.scanCode + << ", metaState=0x" << entry.metaState << ", repeatCount=" << std::dec + << entry.repeatCount << ", downTime=" << entry.downTime; } void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, const std::shared_ptr<const SensorEntry>& entry, DropReason* dropReason, nsecs_t& nextWakeupTime) { - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, " - "source=0x%x, sensorType=%s", - entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source, - ftl::enum_string(entry->sensorType).c_str()); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "notifySensorEvent eventTime=" << entry->eventTime + << ", hwTimestamp=" << entry->hwTimestamp << ", deviceId=" << entry->deviceId + << ", source=0x" << std::hex << entry->source << std::dec + << ", sensorType=" << ftl::enum_string(entry->sensorType); auto command = [this, entry]() REQUIRES(mLock) { scoped_unlock unlock(mLock); @@ -2041,10 +1997,9 @@ void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, } bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) { - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId, - ftl::enum_string(sensorType).c_str()); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "flushSensor deviceId=" << deviceId + << ", sensorType=" << ftl::enum_string(sensorType).c_str(); { // acquire lock std::scoped_lock _l(mLock); @@ -2094,7 +2049,15 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, } Result<std::vector<InputTarget>, InputEventInjectionResult> result = - findTouchedWindowTargetsLocked(currentTime, *entry); + mTouchStates + .findTouchedWindowTargets(currentTime, *entry, + mDragState ? mDragState->dragWindow : nullptr, + std::bind_front(&InputDispatcher:: + addDragEventLocked, + this), + std::bind_front(&InputDispatcher:: + logDispatchStateLocked, + this)); if (result.ok()) { inputTargets = std::move(*result); @@ -2163,7 +2126,8 @@ void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowH void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<const DragEntry> entry) { - std::shared_ptr<Connection> connection = getConnectionLocked(entry->connectionToken); + std::shared_ptr<Connection> connection = + mConnectionManager.getConnection(entry->connectionToken); if (connection == nullptr) { return; // Connection has gone away } @@ -2204,9 +2168,7 @@ void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, std::shared_ptr<const EventEntry> eventEntry, const std::vector<InputTarget>& inputTargets) { ATRACE_CALL(); - if (DEBUG_DISPATCH_CYCLE) { - ALOGD("dispatchEventToCurrentInputTargets"); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) << "dispatchEventToCurrentInputTargets"; processInteractionsLocked(*eventEntry, inputTargets); @@ -2249,9 +2211,7 @@ void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection> } void InputDispatcher::resetNoFocusedWindowTimeoutLocked() { - if (DEBUG_FOCUS) { - ALOGD("Resetting ANR timeouts."); - } + LOG_IF(INFO, DEBUG_FOCUS) << "Resetting ANR timeouts."; // Reset input target wait timeout. mNoFocusedWindowTimeoutTime = std::nullopt; @@ -2338,7 +2298,8 @@ InputDispatcher::findFocusedWindowTargetLocked(nsecs_t currentTime, const EventE } // Drop key events if requested by input feature - if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) { + if (focusedWindowHandle != nullptr && + shouldDropInput(entry, focusedWindowHandle, mWindowInfos)) { return injectionError(InputEventInjectionResult::FAILED); } @@ -2407,28 +2368,11 @@ InputDispatcher::findFocusedWindowTargetLocked(nsecs_t currentTime, const EventE return focusedWindowHandle; } -/** - * Given a list of monitors, remove the ones we cannot find a connection for, and the ones - * that are currently unresponsive. - */ -std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked( - const std::vector<Monitor>& monitors) const { - std::vector<Monitor> responsiveMonitors; - std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors), - [](const Monitor& monitor) REQUIRES(mLock) { - std::shared_ptr<Connection> connection = monitor.connection; - if (!connection->responsive) { - ALOGW("Unresponsive monitor %s will not get the new gesture", - connection->getInputChannelName().c_str()); - return false; - } - return true; - }); - return responsiveMonitors; -} - -base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult> -InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) { +base::Result<std::vector<InputTarget>, os::InputEventInjectionResult> +InputDispatcher::DispatcherTouchState::findTouchedWindowTargets( + nsecs_t currentTime, const MotionEntry& entry, + const sp<android::gui::WindowInfoHandle> dragWindow, + std::function<void(const MotionEntry&)> addDragEvent, std::function<void()> dump) { ATRACE_CALL(); std::vector<InputTarget> targets; @@ -2439,16 +2383,15 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio const int32_t maskedAction = MotionEvent::getActionMasked(action); // Copy current touch state into tempTouchState. - // This state will be used to update mTouchStatesByDisplay at the end of this function. + // This state will be used to update saved touch state at the end of this function. // If no state for the specified display exists, then our initial state will be empty. - const TouchState* oldState = nullptr; + const TouchState* oldState = getTouchStateForMotionEntry(entry); TouchState tempTouchState; - if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) { - oldState = &(it->second); + if (oldState != nullptr) { tempTouchState = *oldState; } - bool isSplit = shouldSplitTouch(tempTouchState, entry); + const bool isSplit = shouldSplitTouch(entry.source); const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || @@ -2461,11 +2404,6 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio const bool newGesture = isDown || maskedAction == AMOTION_EVENT_ACTION_SCROLL || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE; - const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE); - - if (newGesture) { - isSplit = false; - } if (isDown && tempTouchState.hasHoveringPointers(entry.deviceId)) { // Compatibility behaviour: ACTION_DOWN causes HOVER_EXIT to get generated. @@ -2496,22 +2434,11 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus); if (isDown) { - targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id); + targets += findOutsideTargets(displayId, newTouchedWindowHandle, pointer.id, dump); } LOG_IF(INFO, newTouchedWindowHandle == nullptr) << "No new touched window at (" << std::format("{:.1f}, {:.1f}", x, y) << ") in display " << displayId; - // Handle the case where we did not find a window. - if (!input_flags::split_all_touches()) { - // If we are force splitting all touches, then touches outside of the window should - // be dropped, even if this device already has pointers down in another window. - if (newTouchedWindowHandle == nullptr) { - // Try to assign the pointer to the first foreground window we find, if there is - // one. - newTouchedWindowHandle = - tempTouchState.getFirstForegroundWindowHandle(entry.deviceId); - } - } // Verify targeted injection. if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) { @@ -2519,28 +2446,8 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio return injectionError(InputEventInjectionResult::TARGET_MISMATCH); } - // Figure out whether splitting will be allowed for this window. - if (newTouchedWindowHandle != nullptr) { - if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) { - // New window supports splitting, but we should never split mouse events. - isSplit = !isFromMouse; - } else if (isSplit) { - // New window does not support splitting but we have already split events. - // Ignore the new window. - LOG(INFO) << "Skipping " << newTouchedWindowHandle->getName() - << " because it doesn't support split touch"; - newTouchedWindowHandle = nullptr; - } - } else { - // No window is touched, so set split to true. This will allow the next pointer down to - // be delivered to a new window which supports split touch. Pointers from a mouse device - // should never be split. - isSplit = !isFromMouse; - } - std::vector<sp<WindowInfoHandle>> newTouchedWindows = - mWindowInfos.findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId, - mTouchStatesByDisplay); + findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId, mWindowInfos); if (newTouchedWindowHandle != nullptr) { // Process the foreground window first so that it is the first to receive the event. newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle); @@ -2553,7 +2460,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio } for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) { - if (!canWindowReceiveMotionLocked(windowHandle, entry)) { + if (!canWindowReceiveMotion(windowHandle, entry)) { continue; } @@ -2564,21 +2471,8 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio } // Set target flags. - ftl::Flags<InputTarget::Flags> targetFlags; - - if (canReceiveForegroundTouches(*windowHandle->getInfo())) { - // There should only be one touched window that can be "foreground" for the pointer. - targetFlags |= InputTarget::Flags::FOREGROUND; - } - - if (isSplit) { - targetFlags |= InputTarget::Flags::SPLIT; - } - if (isWindowObscuredAtPointLocked(windowHandle, x, y)) { - targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED; - } else if (isWindowObscuredLocked(windowHandle)) { - targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED; - } + ftl::Flags<InputTarget::Flags> targetFlags = + getTargetFlags(windowHandle, {x, y}, isSplit); // Update the temporary touch state. @@ -2596,7 +2490,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio if (!addResult.ok()) { LOG(ERROR) << "Error while processing " << entry << " for " << windowHandle->getName(); - logDispatchStateLocked(); + dump(); } // If this is the pointer going down and the touched window has a wallpaper // then also add the touched wallpaper windows so they are locked in for the @@ -2607,7 +2501,8 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) && windowHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) { - sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle); + sp<WindowInfoHandle> wallpaper = + mWindowInfos.findWallpaperWindowBelow(windowHandle); if (wallpaper != nullptr) { ftl::Flags<InputTarget::Flags> wallpaperFlags = InputTarget::Flags::WINDOW_IS_OBSCURED | @@ -2645,11 +2540,10 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio // If the pointer is not currently down, then ignore the event. if (!tempTouchState.isDown(entry.deviceId) && maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) { - if (DEBUG_DROPPED_EVENTS_VERBOSE) { - LOG(INFO) << "Dropping event because the pointer for device " << entry.deviceId - << " is not down or we previously dropped the pointer down event in " - << "display " << displayId << ": " << entry.getDescription(); - } + LOG_IF(INFO, DEBUG_DROPPED_EVENTS_VERBOSE) + << "Dropping event because the pointer for device " << entry.deviceId + << " is not down or we previously dropped the pointer down event in display " + << displayId << ": " << entry.getDescription(); return injectionError(InputEventInjectionResult::FAILED); } @@ -2666,7 +2560,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio tempTouchState.removeHoveringPointer(entry.deviceId, pointerId); } - addDragEventLocked(entry); + addDragEvent(entry); // Check whether touches should slip outside of the current foreground window. if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 && @@ -2687,7 +2581,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio // Do not slide events to the window which can not receive motion event if (newTouchedWindowHandle != nullptr && - !canWindowReceiveMotionLocked(newTouchedWindowHandle, entry)) { + !canWindowReceiveMotion(newTouchedWindowHandle, entry)) { newTouchedWindowHandle = nullptr; } @@ -2704,29 +2598,16 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio const TouchedWindow& touchedWindow = tempTouchState.getTouchedWindow(oldTouchedWindowHandle); - addPointerWindowTargetLocked(oldTouchedWindowHandle, - InputTarget::DispatchMode::SLIPPERY_EXIT, - ftl::Flags<InputTarget::Flags>(), pointerIds, - touchedWindow.getDownTimeInTarget(entry.deviceId), - targets); + addPointerWindowTarget(oldTouchedWindowHandle, + InputTarget::DispatchMode::SLIPPERY_EXIT, + ftl::Flags<InputTarget::Flags>(), pointerIds, + touchedWindow.getDownTimeInTarget(entry.deviceId), + /*pointerDisplayId=*/std::nullopt, dump, targets); // Make a slippery entrance into the new window. - if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) { - isSplit = !isFromMouse; - } - ftl::Flags<InputTarget::Flags> targetFlags; - if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) { - targetFlags |= InputTarget::Flags::FOREGROUND; - } - if (isSplit) { - targetFlags |= InputTarget::Flags::SPLIT; - } - if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) { - targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED; - } else if (isWindowObscuredLocked(newTouchedWindowHandle)) { - targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED; - } + ftl::Flags<InputTarget::Flags> targetFlags = + getTargetFlags(newTouchedWindowHandle, {x, y}, isSplit); tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, InputTarget::DispatchMode::SLIPPERY_ENTER, @@ -2735,7 +2616,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio // Check if the wallpaper window should deliver the corresponding event. slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle, - tempTouchState, entry, targets); + tempTouchState, entry, targets, dump); tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id, oldTouchedWindowHandle); } @@ -2748,7 +2629,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]}; for (TouchedWindow& touchedWindow : tempTouchState.windows) { // Ignore drag window for it should just track one pointer. - if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) { + if (dragWindow == touchedWindow.windowHandle) { continue; } if (!touchedWindow.hasTouchingPointers(entry.deviceId)) { @@ -2762,17 +2643,15 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio // Update dispatching for hover enter and exit. { std::vector<TouchedWindow> hoveringWindows = - getHoveringWindowsLocked(oldState, tempTouchState, entry, - std::bind_front(&InputDispatcher::logDispatchStateLocked, - this)); + getHoveringWindowsLocked(oldState, tempTouchState, entry, dump); // Hardcode to single hovering pointer for now. std::bitset<MAX_POINTER_ID + 1> pointerIds; pointerIds.set(entry.pointerProperties[0].id); for (const TouchedWindow& touchedWindow : hoveringWindows) { - addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode, - touchedWindow.targetFlags, pointerIds, - touchedWindow.getDownTimeInTarget(entry.deviceId), - targets); + addPointerWindowTarget(touchedWindow.windowHandle, touchedWindow.dispatchMode, + touchedWindow.targetFlags, pointerIds, + touchedWindow.getDownTimeInTarget(entry.deviceId), + /*pointerDisplayId=*/std::nullopt, dump, targets); } } @@ -2825,9 +2704,10 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio if (touchingPointers.empty()) { continue; } - addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode, - touchedWindow.targetFlags, getPointerIds(touchingPointers), - touchedWindow.getDownTimeInTarget(entry.deviceId), targets); + addPointerWindowTarget(touchedWindow.windowHandle, touchedWindow.dispatchMode, + touchedWindow.targetFlags, getPointerIds(touchingPointers), + touchedWindow.getDownTimeInTarget(entry.deviceId), + /*pointerDisplayId=*/displayId, dump, targets); } // During targeted injection, only allow owned targets to receive events @@ -2882,16 +2762,12 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) { if (displayId >= ui::LogicalDisplayId::DEFAULT) { tempTouchState.clearWindowsWithoutPointers(); - mTouchStatesByDisplay[displayId] = tempTouchState; + saveTouchStateForMotionEntry(entry, std::move(tempTouchState)); } else { - mTouchStatesByDisplay.erase(displayId); + eraseTouchStateForMotionEntry(entry); } } - if (tempTouchState.windows.empty()) { - mTouchStatesByDisplay.erase(displayId); - } - return targets; } @@ -2914,8 +2790,9 @@ void InputDispatcher::finishDragAndDrop(ui::LogicalDisplayId displayId, float x, } void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { - if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId || - mDragState->deviceId != entry.deviceId) { + if (!mDragState || mDragState->deviceId != entry.deviceId || + !mWindowInfos.areDisplaysConnected(mDragState->dragWindow->getInfo()->displayId, + entry.displayId)) { return; } @@ -3007,17 +2884,17 @@ void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHa const WindowInfo* windowInfo = windowHandle->getInfo(); if (it == inputTargets.end()) { - std::shared_ptr<Connection> connection = getConnectionLocked(windowHandle->getToken()); + std::shared_ptr<Connection> connection = + mConnectionManager.getConnection(windowHandle->getToken()); if (connection == nullptr) { ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str()); return; } - inputTargets.push_back(createInputTarget(connection, windowHandle, dispatchMode, - targetFlags, - mWindowInfos.getDisplayTransform( - windowHandle->getInfo()->displayId), - firstDownTimeInTarget)); + inputTargets.push_back( + createInputTarget(connection, windowHandle, dispatchMode, targetFlags, + mWindowInfos.getRawTransform(*windowHandle->getInfo()), + firstDownTimeInTarget)); it = inputTargets.end() - 1; } @@ -3030,11 +2907,12 @@ void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHa } } -void InputDispatcher::addPointerWindowTargetLocked( +void InputDispatcher::DispatcherTouchState::addPointerWindowTarget( const sp<android::gui::WindowInfoHandle>& windowHandle, InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags, std::bitset<MAX_POINTER_ID + 1> pointerIds, std::optional<nsecs_t> firstDownTimeInTarget, - std::vector<InputTarget>& inputTargets) const REQUIRES(mLock) { + std::optional<ui::LogicalDisplayId> pointerDisplayId, std::function<void()> dump, + std::vector<InputTarget>& inputTargets) { if (pointerIds.none()) { for (const auto& target : inputTargets) { LOG(INFO) << "Target: " << target; @@ -3059,20 +2937,19 @@ void InputDispatcher::addPointerWindowTargetLocked( it = inputTargets.end(); } - const WindowInfo* windowInfo = windowHandle->getInfo(); + const WindowInfo& windowInfo = *windowHandle->getInfo(); if (it == inputTargets.end()) { - std::shared_ptr<Connection> connection = getConnectionLocked(windowHandle->getToken()); + std::shared_ptr<Connection> connection = mConnectionManager.getConnection(windowInfo.token); if (connection == nullptr) { - ALOGW("Not creating InputTarget for %s, no input channel", - windowHandle->getName().c_str()); + ALOGW("Not creating InputTarget for %s, no input channel", windowInfo.name.c_str()); return; } - inputTargets.push_back(createInputTarget(connection, windowHandle, dispatchMode, - targetFlags, - mWindowInfos.getDisplayTransform( - windowHandle->getInfo()->displayId), - firstDownTimeInTarget)); + inputTargets.push_back( + createInputTarget(connection, windowHandle, dispatchMode, targetFlags, + mWindowInfos.getRawTransform(*windowHandle->getInfo(), + pointerDisplayId), + firstDownTimeInTarget)); it = inputTargets.end() - 1; } @@ -3084,31 +2961,44 @@ void InputDispatcher::addPointerWindowTargetLocked( LOG(ERROR) << __func__ << ": Flags don't match! new targetFlags=" << targetFlags.string() << ", it=" << *it; } - if (it->globalScaleFactor != windowInfo->globalScaleFactor) { + if (it->globalScaleFactor != windowInfo.globalScaleFactor) { LOG(ERROR) << __func__ << ": Mismatch! it->globalScaleFactor=" << it->globalScaleFactor - << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor; + << ", windowInfo->globalScaleFactor=" << windowInfo.globalScaleFactor; } - Result<void> result = it->addPointers(pointerIds, windowInfo->transform); + Result<void> result = it->addPointers(pointerIds, windowInfo.transform); if (!result.ok()) { - logDispatchStateLocked(); + dump(); LOG(FATAL) << result.error().message(); } } void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, ui::LogicalDisplayId displayId) { - auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId); - if (monitorsIt == mGlobalMonitorsByDisplay.end()) return; - - for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) { - InputTarget target{monitor.connection}; - // target.firstDownTimeInTarget is not set for global monitors. It is only required in split - // touch and global monitoring works as intended even without setting firstDownTimeInTarget - target.displayTransform = mWindowInfos.getDisplayTransform(displayId); - target.setDefaultPointerTransform(target.displayTransform); - inputTargets.push_back(target); - } + mConnectionManager + .forEachGlobalMonitorConnection(displayId, + [&](const std::shared_ptr<Connection>& connection) { + if (!connection->responsive) { + ALOGW("Ignoring unrsponsive monitor: %s", + connection->getInputChannelName() + .c_str()); + return; + } + + InputTarget target{connection}; + // target.firstDownTimeInTarget is not set for + // global monitors. It is only required in split + // touch and global monitoring works as intended + // even without setting firstDownTimeInTarget. Since + // global monitors don't have windows, use the + // display transform as the raw transform. + base::ScopedLockAssertion assumeLocked(mLock); + target.rawTransform = + mWindowInfos.getDisplayTransform(displayId); + target.setDefaultPointerTransform( + target.rawTransform); + inputTargets.push_back(target); + }); } /** @@ -3164,12 +3054,12 @@ static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle, * * If neither of those is true, then it means the touch can be allowed. */ -InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked( +InputDispatcher::DispatcherWindowInfo::TouchOcclusionInfo +InputDispatcher::DispatcherWindowInfo::computeTouchOcclusionInfo( const sp<WindowInfoHandle>& windowHandle, float x, float y) const { const WindowInfo* windowInfo = windowHandle->getInfo(); ui::LogicalDisplayId displayId = windowInfo->displayId; - const std::vector<sp<WindowInfoHandle>>& windowHandles = - mWindowInfos.getWindowHandlesForDisplay(displayId); + const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId); TouchOcclusionInfo info; info.hasBlockingOcclusion = false; info.obscuringOpacity = 0; @@ -3181,12 +3071,11 @@ InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLo } const WindowInfo* otherInfo = otherHandle->getInfo(); if (canBeObscuredBy(windowHandle, otherHandle) && - windowOccludesTouchAt(*otherInfo, displayId, x, y, - mWindowInfos.getDisplayTransform(displayId)) && + windowOccludesTouchAt(*otherInfo, displayId, x, y, getDisplayTransform(displayId)) && !haveSameApplicationToken(windowInfo, otherInfo)) { if (DEBUG_TOUCH_OCCLUSION) { info.debugInfo.push_back( - dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false)); + dumpWindowForTouchOcclusion(*otherInfo, /*isTouchedWindow=*/false)); } // canBeObscuredBy() has returned true above, which means this window is untrusted, so // we perform the checks below to see if the touch can be propagated or not based on the @@ -3214,28 +3103,14 @@ InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLo } } if (DEBUG_TOUCH_OCCLUSION) { - info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true)); + info.debugInfo.push_back( + dumpWindowForTouchOcclusion(*windowInfo, /*isTouchedWindow=*/true)); } return info; } -std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info, - bool isTouchedWindow) const { - return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, " - "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32 - "], touchableRegion=%s, window={%s}, inputConfig={%s}, " - "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n", - isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(), - info->ownerUid.toString().c_str(), info->id, - toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left, - info->frame.top, info->frame.right, info->frame.bottom, - dumpRegion(info->touchableRegion).c_str(), info->name.c_str(), - info->inputConfig.string().c_str(), toString(info->token != nullptr), - info->applicationInfo.name.c_str(), - binderToString(info->applicationInfo.token).c_str()); -} - -bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const { +bool InputDispatcher::DispatcherWindowInfo::isTouchTrusted( + const TouchOcclusionInfo& occlusionInfo) const { if (occlusionInfo.hasBlockingOcclusion) { ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid.toString().c_str()); @@ -3251,29 +3126,27 @@ bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionIn return true; } -bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle, - float x, float y) const { +bool InputDispatcher::DispatcherWindowInfo::isWindowObscuredAtPoint( + const sp<WindowInfoHandle>& windowHandle, float x, float y) const { ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId; - const std::vector<sp<WindowInfoHandle>>& windowHandles = - mWindowInfos.getWindowHandlesForDisplay(displayId); + const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId); for (const sp<WindowInfoHandle>& otherHandle : windowHandles) { if (windowHandle == otherHandle) { break; // All future windows are below us. Exit early. } const WindowInfo* otherInfo = otherHandle->getInfo(); if (canBeObscuredBy(windowHandle, otherHandle) && - windowOccludesTouchAt(*otherInfo, displayId, x, y, - mWindowInfos.getDisplayTransform(displayId))) { + windowOccludesTouchAt(*otherInfo, displayId, x, y, getDisplayTransform(displayId))) { return true; } } return false; } -bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const { +bool InputDispatcher::DispatcherWindowInfo::isWindowObscured( + const sp<WindowInfoHandle>& windowHandle) const { ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId; - const std::vector<sp<WindowInfoHandle>>& windowHandles = - mWindowInfos.getWindowHandlesForDisplay(displayId); + const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId); const WindowInfo* windowInfo = windowHandle->getInfo(); for (const sp<WindowInfoHandle>& otherHandle : windowHandles) { if (windowHandle == otherHandle) { @@ -3339,10 +3212,9 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) { return; } if (windowDisablingUserActivityInfo != nullptr) { - if (DEBUG_DISPATCH_CYCLE) { - ALOGD("Not poking user activity: disabled by window '%s'.", - windowDisablingUserActivityInfo->name.c_str()); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) + << "Not poking user activity: disabled by window '" + << windowDisablingUserActivityInfo->name << "'."; return; } break; @@ -3356,10 +3228,9 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) { // the apps, like system shortcuts if (windowDisablingUserActivityInfo != nullptr && keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP) { - if (DEBUG_DISPATCH_CYCLE) { - ALOGD("Not poking user activity: disabled by window '%s'.", - windowDisablingUserActivityInfo->name.c_str()); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) + << "Not poking user activity: disabled by window '" + << windowDisablingUserActivityInfo->name << "'."; return; } break; @@ -3387,22 +3258,19 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, ATRACE_NAME_IF(ATRACE_ENABLED(), StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")", connection->getInputChannelName().c_str(), eventEntry->id)); - if (DEBUG_DISPATCH_CYCLE) { - ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, " - "globalScaleFactor=%f, pointerIds=%s %s", - connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(), - inputTarget.globalScaleFactor, bitsetToString(inputTarget.getPointerIds()).c_str(), - inputTarget.getPointerInfoString().c_str()); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) + << "channel '" << connection->getInputChannelName() + << "' ~ prepareDispatchCycle - flags=" << inputTarget.flags.string() + << ", globalScaleFactor=" << inputTarget.globalScaleFactor + << ", pointerIds=" << bitsetToString(inputTarget.getPointerIds()) << " " + << inputTarget.getPointerInfoString(); // Skip this event if the connection status is not normal. // We don't want to enqueue additional outbound events if the connection is broken. if (connection->status != Connection::Status::NORMAL) { - if (DEBUG_DISPATCH_CYCLE) { - ALOGD("channel '%s' ~ Dropping event because the channel status is %s", - connection->getInputChannelName().c_str(), - ftl::enum_string(connection->status).c_str()); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) << "channel '" << connection->getInputChannelName() + << "' ~ Dropping event because the channel status is " + << ftl::enum_string(connection->status); return; } @@ -3521,11 +3389,10 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE && !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source, motionEntry.displayId)) { - if (DEBUG_DISPATCH_CYCLE) { - LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str() - << "' ~ enqueueDispatchEntryLocked: filling in missing hover " - "enter event"; - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) + << "channel '" << connection->getInputChannelName().c_str() + << "' ~ enqueueDispatchEntryLocked: filling in missing hover enter " + "event"; resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER; } @@ -3819,9 +3686,8 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, ATRACE_NAME_IF(ATRACE_ENABLED(), StringPrintf("startDispatchCycleLocked(inputChannel=%s)", connection->getInputChannelName().c_str())); - if (DEBUG_DISPATCH_CYCLE) { - ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str()); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) + << "channel '" << connection->getInputChannelName() << "' ~ startDispatchCycle"; while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) { std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front(); @@ -3836,10 +3702,9 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, case EventEntry::Type::KEY: { const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry); std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry); - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - LOG(INFO) << "Publishing " << *dispatchEntry << " to " - << connection->getInputChannelName(); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "Publishing " << *dispatchEntry << " to " + << connection->getInputChannelName(); // Publish the key event. status = connection->inputPublisher @@ -3858,10 +3723,9 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, } case EventEntry::Type::MOTION: { - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - LOG(INFO) << "Publishing " << *dispatchEntry << " to " - << connection->getInputChannelName(); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "Publishing " << *dispatchEntry << " to " + << connection->getInputChannelName(); const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry); status = publishMotionEvent(*connection, *dispatchEntry); if (status == BAD_VALUE) { @@ -3930,22 +3794,21 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, "event to it, status=%s(%d)", connection->getInputChannelName().c_str(), statusToString(status).c_str(), status); - abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true); + abortBrokenDispatchCycleLocked(connection, /*notify=*/true); } else { // Pipe is full and we are waiting for the app to finish process some events // before sending more events to it. - if (DEBUG_DISPATCH_CYCLE) { - ALOGD("channel '%s' ~ Could not publish event because the pipe is full, " - "waiting for the application to catch up", - connection->getInputChannelName().c_str()); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) + << "channel '" << connection->getInputChannelName() + << "' ~ Could not publish event because the pipe is full, waiting for " + "the application to catch up"; } } else { ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, " "status=%s(%d)", connection->getInputChannelName().c_str(), statusToString(status).c_str(), status); - abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true); + abortBrokenDispatchCycleLocked(connection, /*notify=*/true); } return; } @@ -4004,10 +3867,9 @@ const std::array<uint8_t, 32> InputDispatcher::getSignature( void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, const std::shared_ptr<Connection>& connection, uint32_t seq, bool handled, nsecs_t consumeTime) { - if (DEBUG_DISPATCH_CYCLE) { - ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s", - connection->getInputChannelName().c_str(), seq, toString(handled)); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) + << "channel '" << connection->getInputChannelName() + << "' ~ finishDispatchCycle - seq=" << seq << ", handled=" << toString(handled); if (connection->status != Connection::Status::NORMAL) { return; @@ -4020,13 +3882,10 @@ void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, postCommandLocked(std::move(command)); } -void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime, - const std::shared_ptr<Connection>& connection, +void InputDispatcher::abortBrokenDispatchCycleLocked(const std::shared_ptr<Connection>& connection, bool notify) { - if (DEBUG_DISPATCH_CYCLE) { - LOG(INFO) << "channel '" << connection->getInputChannelName() << "'~ " << __func__ - << " - notify=" << toString(notify); - } + LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) << "channel '" << connection->getInputChannelName() << "'~ " + << __func__ << " - notify=" << toString(notify); // Clear the dispatch queues. drainDispatchQueue(connection->outboundQueue); @@ -4068,7 +3927,7 @@ void InputDispatcher::releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispat int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) { std::scoped_lock _l(mLock); - std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken); + std::shared_ptr<Connection> connection = mConnectionManager.getConnection(connectionToken); if (connection == nullptr) { ALOGW("Received looper callback for unknown input channel token %p. events=0x%x", connectionToken.get(), events); @@ -4137,7 +3996,7 @@ int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionTok } // Remove the channel. - removeInputChannelLocked(connection->getToken(), notify); + removeInputChannelLocked(connection, notify); return 0; // remove the callback } @@ -4151,13 +4010,17 @@ void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked( // Generate cancellations for touched windows first. This is to avoid generating cancellations // through a non-touched window if there are more than one window for an input channel. if (cancelPointers) { - for (const auto& [displayId, touchState] : mTouchStatesByDisplay) { - if (options.displayId.has_value() && options.displayId != displayId) { - continue; - } - for (const auto& touchedWindow : touchState.windows) { - synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options); - } + if (options.displayId.has_value()) { + mTouchStates.forAllTouchedWindowsOnDisplay( + options.displayId.value(), [&](const sp<gui::WindowInfoHandle>& windowHandle) { + base::ScopedLockAssertion assumeLocked(mLock); + synthesizeCancelationEventsForWindowLocked(windowHandle, options); + }); + } else { + mTouchStates.forAllTouchedWindows([&](const sp<gui::WindowInfoHandle>& windowHandle) { + base::ScopedLockAssertion assumeLocked(mLock); + synthesizeCancelationEventsForWindowLocked(windowHandle, options); + }); } } // Follow up by generating cancellations for all windows, because we don't explicitly track @@ -4176,12 +4039,12 @@ void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked( void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked( const CancelationOptions& options) { - for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) { - for (const Monitor& monitor : monitors) { - synthesizeCancelationEventsForConnectionLocked(monitor.connection, options, - /*window=*/nullptr); - } - } + mConnectionManager.forEachGlobalMonitorConnection( + [&](const std::shared_ptr<Connection>& connection) { + base::ScopedLockAssertion assumeLocked(mLock); + synthesizeCancelationEventsForConnectionLocked(connection, options, + /*window=*/nullptr); + }); } void InputDispatcher::synthesizeCancelationEventsForWindowLocked( @@ -4199,7 +4062,7 @@ void InputDispatcher::synthesizeCancelationEventsForWindowLocked( } std::shared_ptr<Connection> resolvedConnection = - connection ? connection : getConnectionLocked(windowHandle->getToken()); + connection ? connection : mConnectionManager.getConnection(windowHandle->getToken()); if (!resolvedConnection) { LOG(DEBUG) << __func__ << "No connection found for window: " << windowHandle->getName(); return; @@ -4228,12 +4091,11 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( return; } - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync " - "with reality: %s, mode=%s.", - connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason, - ftl::enum_string(options.mode).c_str()); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "channel '" << connection->getInputChannelName() << "' ~ Synthesized " + << cancelationEvents.size() + << " cancelation events to bring channel back in sync with reality: " << options.reason + << ", mode=" << ftl::enum_string(options.mode) << "."; std::string reason = std::string("reason=").append(options.reason); android_log_event_list(LOGTAG_INPUT_CANCEL) @@ -4286,14 +4148,21 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( sendDropWindowCommandLocked(nullptr, /*x=*/0, /*y=*/0); mDragState.reset(); } - addPointerWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS, - ftl::Flags<InputTarget::Flags>(), pointerIds, - motionEntry.downTime, targets); + mTouchStates + .addPointerWindowTarget(window, InputTarget::DispatchMode::AS_IS, + ftl::Flags<InputTarget::Flags>(), pointerIds, + motionEntry.downTime, + /*pointerDisplayId=*/std::nullopt, + std::bind_front(&InputDispatcher:: + logDispatchStateLocked, + this), + targets); } else { targets.emplace_back(fallbackTarget); + // Since we don't have a window, use the display transform as the raw transform. const ui::Transform displayTransform = mWindowInfos.getDisplayTransform(motionEntry.displayId); - targets.back().displayTransform = displayTransform; + targets.back().rawTransform = displayTransform; targets.back().setDefaultPointerTransform(displayTransform); } logOutboundMotionDetails("cancel - ", motionEntry); @@ -4343,17 +4212,12 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( return; } - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.", - connection->getInputChannelName().c_str(), downEvents.size()); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "channel '" << connection->getInputChannelName() << "' ~ Synthesized " + << downEvents.size() << " down events to ensure consistent event stream."; - const auto [_, touchedWindowState, displayId] = - findTouchStateWindowAndDisplay(connection->getToken(), mTouchStatesByDisplay); - if (touchedWindowState == nullptr) { - LOG(FATAL) << __func__ << ": Touch state is out of sync: No touched window for token"; - } - const auto& windowHandle = touchedWindowState->windowHandle; + const auto [windowHandle, displayId] = + mTouchStates.findExistingTouchedWindowHandleAndDisplay(connection->getToken()); const bool wasEmpty = connection->outboundQueue.empty(); for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) { @@ -4371,14 +4235,20 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( pointerIndex++) { pointerIds.set(motionEntry.pointerProperties[pointerIndex].id); } - addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::AS_IS, - targetFlags, pointerIds, motionEntry.downTime, - targets); + mTouchStates + .addPointerWindowTarget(windowHandle, InputTarget::DispatchMode::AS_IS, + targetFlags, pointerIds, motionEntry.downTime, + /*pointerDisplayId=*/std::nullopt, + std::bind_front(&InputDispatcher:: + logDispatchStateLocked, + this), + targets); } else { targets.emplace_back(connection, targetFlags); + // Since we don't have a window, use the display transform as the raw transform. const ui::Transform displayTransform = mWindowInfos.getDisplayTransform(motionEntry.displayId); - targets.back().displayTransform = displayTransform; + targets.back().rawTransform = displayTransform; targets.back().setDefaultPointerTransform(displayTransform); } logOutboundMotionDetails("down - ", motionEntry); @@ -4479,15 +4349,15 @@ void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedA } void InputDispatcher::notifyKey(const NotifyKeyArgs& args) { - ALOGD_IF(debugInboundEventDetails(), - "notifyKey - id=%" PRIx32 ", eventTime=%" PRId64 - ", deviceId=%d, source=%s, displayId=%s, policyFlags=0x%x, action=%s, flags=0x%x, " - "keyCode=%s, scanCode=0x%x, metaState=0x%x, " - "downTime=%" PRId64, - args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(), - args.displayId.toString().c_str(), args.policyFlags, - KeyEvent::actionToString(args.action), args.flags, KeyEvent::getLabel(args.keyCode), - args.scanCode, args.metaState, args.downTime); + LOG_IF(INFO, debugInboundEventDetails()) + << "notifyKey - id=" << args.id << ", eventTime=" << args.eventTime + << ", deviceId=" << args.deviceId + << ", source=" << inputEventSourceToString(args.source) + << ", displayId=" << args.displayId.toString() << ", policyFlags=0x" << std::hex + << args.policyFlags << ", action=" << KeyEvent::actionToString(args.action) + << ", flags=0x" << args.flags << ", keyCode=" << KeyEvent::getLabel(args.keyCode) + << ", scanCode=0x" << args.scanCode << ", metaState=0x" << args.metaState + << ", downTime=" << std::dec << args.downTime; Result<void> keyCheck = validateKeyEvent(args.action); if (!keyCheck.ok()) { LOG(ERROR) << "invalid key event: " << keyCheck.error(); @@ -4615,8 +4485,9 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) { args.displayId.toString().c_str())); Result<void> result = it->second.processMovement(args.deviceId, args.source, args.action, - args.getPointerCount(), args.pointerProperties.data(), - args.pointerCoords.data(), args.flags); + args.actionButton, args.getPointerCount(), + args.pointerProperties.data(), args.pointerCoords.data(), + args.flags, args.buttonState); if (!result.ok()) { LOG(FATAL) << "Bad stream: " << result.error() << " caused by " << args.dump(); } @@ -4639,13 +4510,8 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) { if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) { // Set the flag anyway if we already have an ongoing gesture. That would allow us to // complete the processing of the current stroke. - const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId); - if (touchStateIt != mTouchStatesByDisplay.end()) { - const TouchState& touchState = touchStateIt->second; - if (touchState.hasTouchingPointers(args.deviceId) || - touchState.hasHoveringPointers(args.deviceId)) { - policyFlags |= POLICY_FLAG_PASS_TO_USER; - } + if (mTouchStates.hasTouchingOrHoveringPointers(args.displayId, args.deviceId)) { + policyFlags |= POLICY_FLAG_PASS_TO_USER; } } @@ -4701,12 +4567,10 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) { } void InputDispatcher::notifySensor(const NotifySensorArgs& args) { - if (debugInboundEventDetails()) { - ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, " - " sensorType=%s", - args.id, args.eventTime, args.deviceId, args.source, - ftl::enum_string(args.sensorType).c_str()); - } + LOG_IF(INFO, debugInboundEventDetails()) + << "notifySensor - id=" << args.id << " eventTime=" << args.eventTime + << ", deviceId=" << args.deviceId << ", source=0x" << std::hex << args.source + << std::dec << ", sensorType=" << ftl::enum_string(args.sensorType); bool needWake = false; { // acquire lock @@ -4728,10 +4592,9 @@ void InputDispatcher::notifySensor(const NotifySensorArgs& args) { } void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs& args) { - if (debugInboundEventDetails()) { - ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args.eventTime, - args.deviceId, args.isOn); - } + LOG_IF(INFO, debugInboundEventDetails()) + << "notifyVibratorState - eventTime=" << args.eventTime << ", device=" << args.deviceId + << ", isOn=" << args.isOn; mPolicy.notifyVibratorState(args.deviceId, args.isOn); } @@ -4740,11 +4603,10 @@ bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs } void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) { - if (debugInboundEventDetails()) { - ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, " - "switchMask=0x%08x", - args.eventTime, args.policyFlags, args.switchValues, args.switchMask); - } + LOG_IF(INFO, debugInboundEventDetails()) + << "notifySwitch - eventTime=" << args.eventTime << ", policyFlags=0x" << std::hex + << args.policyFlags << ", switchValues=0x" << std::setfill('0') << std::setw(8) + << args.switchValues << ", switchMask=0x" << std::setw(8) << args.switchMask; uint32_t policyFlags = args.policyFlags; policyFlags |= POLICY_FLAG_TRUSTED; @@ -4753,10 +4615,8 @@ void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) { void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) { // TODO(b/308677868) Remove device reset from the InputListener interface - if (debugInboundEventDetails()) { - ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args.eventTime, - args.deviceId); - } + LOG_IF(INFO, debugInboundEventDetails()) + << "notifyDeviceReset - eventTime=" << args.eventTime << ", deviceId=" << args.deviceId; bool needWake = false; { // acquire lock @@ -4777,10 +4637,9 @@ void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) { } void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) { - if (debugInboundEventDetails()) { - ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args.eventTime, - args.request.isEnable() ? "true" : "false"); - } + LOG_IF(INFO, debugInboundEventDetails()) + << "notifyPointerCaptureChanged - eventTime=%" << args.eventTime + << ", enabled=" << toString(args.request.isEnable()); bool needWake = false; { // acquire lock @@ -4817,9 +4676,10 @@ bool InputDispatcher::shouldRejectInjectedMotionLocked(const MotionEvent& motion Result<void> result = verifier.processMovement(deviceId, motionEvent.getSource(), motionEvent.getAction(), - motionEvent.getPointerCount(), + motionEvent.getActionButton(), motionEvent.getPointerCount(), motionEvent.getPointerProperties(), - motionEvent.getSamplePointerCoords(), flags); + motionEvent.getSamplePointerCoords(), flags, + motionEvent.getButtonState()); if (!result.ok()) { logDispatchStateLocked(); LOG(ERROR) << "Inconsistent event: " << motionEvent << ", reason: " << result.error(); @@ -4839,12 +4699,10 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev return InputEventInjectionResult::FAILED; } - if (debugInboundEventDetails()) { - LOG(INFO) << __func__ << ": targetUid=" << toString(targetUid, &uidString) - << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count() - << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec - << ", event=" << *event; - } + LOG_IF(INFO, debugInboundEventDetails()) + << __func__ << ": targetUid=" << toString(targetUid, &uidString) + << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count() + << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec << ", event=" << *event; nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count(); policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED; @@ -4936,6 +4794,10 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT; } + if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL) { + flags |= AMOTION_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL; + } + mLock.lock(); if (shouldRejectInjectedMotionLocked(motionEvent, resolvedDeviceId, displayId, @@ -4944,6 +4806,14 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev return InputEventInjectionResult::FAILED; } + if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) { + // Set the flag anyway if we already have an ongoing motion gesture. That + // would allow us to complete the processing of the current stroke. + if (mTouchStates.hasTouchingOrHoveringPointers(displayId, resolvedDeviceId)) { + policyFlags |= POLICY_FLAG_PASS_TO_USER; + } + } + const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes(); const size_t pointerCount = motionEvent.getPointerCount(); const std::vector<PointerProperties> @@ -5009,9 +4879,7 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev bool needWake = false; while (!injectedEntries.empty()) { - if (DEBUG_INJECTION) { - LOG(INFO) << "Injecting " << injectedEntries.front()->getDescription(); - } + LOG_IF(INFO, DEBUG_INJECTION) << "Injecting " << injectedEntries.front()->getDescription(); needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front())); injectedEntries.pop(); } @@ -5037,10 +4905,8 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev nsecs_t remainingTimeout = endTime - now(); if (remainingTimeout <= 0) { - if (DEBUG_INJECTION) { - ALOGD("injectInputEvent - Timed out waiting for injection result " - "to become available."); - } + LOG_IF(INFO, DEBUG_INJECTION) << "injectInputEvent - Timed out waiting for " + "injection result to become available."; injectionResult = InputEventInjectionResult::TIMED_OUT; break; } @@ -5051,16 +4917,14 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev if (injectionResult == InputEventInjectionResult::SUCCEEDED && syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) { while (injectionState->pendingForegroundDispatches != 0) { - if (DEBUG_INJECTION) { - ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.", - injectionState->pendingForegroundDispatches); - } + LOG_IF(INFO, DEBUG_INJECTION) << "injectInputEvent - Waiting for " + << injectionState->pendingForegroundDispatches + << " pending foreground dispatches."; nsecs_t remainingTimeout = endTime - now(); if (remainingTimeout <= 0) { - if (DEBUG_INJECTION) { - ALOGD("injectInputEvent - Timed out waiting for pending foreground " - "dispatches to finish."); - } + LOG_IF(INFO, DEBUG_INJECTION) + << "injectInputEvent - Timed out waiting for pending foreground " + "dispatches to finish."; injectionResult = InputEventInjectionResult::TIMED_OUT; break; } @@ -5071,10 +4935,8 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev } } // release lock - if (DEBUG_INJECTION) { - LOG(INFO) << "injectInputEvent - Finished with result " - << ftl::enum_string(injectionResult); - } + LOG_IF(INFO, DEBUG_INJECTION) << "injectInputEvent - Finished with result " + << ftl::enum_string(injectionResult); return injectionResult; } @@ -5120,10 +4982,8 @@ void InputDispatcher::setInjectionResult(const EventEntry& entry, } InjectionState& injectionState = *entry.injectionState; - if (DEBUG_INJECTION) { - LOG(INFO) << "Setting input event injection result to " - << ftl::enum_string(injectionResult); - } + LOG_IF(INFO, DEBUG_INJECTION) << "Setting input event injection result to " + << ftl::enum_string(injectionResult); if (injectionState.injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) { // Log the outcome since the injector did not wait for the injection result. @@ -5207,8 +5067,19 @@ sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWindowHandle( } // Only look through the requested display. - for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesForDisplay(*displayId)) { - if (windowHandle->getToken() == windowHandleToken) { + return findWindowHandleOnDisplay(windowHandleToken, *displayId); +} + +sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWindowHandleOnConnectedDisplays( + const sp<IBinder>& windowHandleToken, ui::LogicalDisplayId displayId) const { + if (windowHandleToken == nullptr) { + return nullptr; + } + + sp<WindowInfoHandle> windowHandle; + for (ui::LogicalDisplayId connectedDisplayId : getConnectedDisplays(displayId)) { + windowHandle = findWindowHandleOnDisplay(windowHandleToken, connectedDisplayId); + if (windowHandle != nullptr) { return windowHandle; } } @@ -5289,6 +5160,41 @@ ui::Transform InputDispatcher::DispatcherWindowInfo::getDisplayTransform( : kIdentityTransform; } +ui::Transform InputDispatcher::DispatcherWindowInfo::getRawTransform( + const android::gui::WindowInfo& windowInfo, + std::optional<ui::LogicalDisplayId> pointerDisplayId) const { + // TODO(b/383092013): Handle TOPOLOGY_AWARE window flag. + // For now, we assume all windows are topology-aware and can handle cross-display streams. + if (com::android::input::flags::connected_displays_cursor() && pointerDisplayId.has_value() && + *pointerDisplayId != windowInfo.displayId) { + // Sending pointer to a different display than the window. This is a + // cross-display drag gesture, so always use the new display's transform. + return getDisplayTransform(*pointerDisplayId); + } + // If the window has a cloneLayerStackTransform, always use it as the transform for the "getRaw" + // APIs. If not, fall back to using the DisplayInfo transform of the window's display + bool useClonedScreenCoordinates = (input_flags::use_cloned_screen_coordinates_as_raw() && + windowInfo.cloneLayerStackTransform); + if (useClonedScreenCoordinates) { + return *windowInfo.cloneLayerStackTransform; + } + return getDisplayTransform(windowInfo.displayId); +} + +ui::LogicalDisplayId InputDispatcher::DispatcherWindowInfo::getPrimaryDisplayId( + ui::LogicalDisplayId displayId) const { + if (mTopology.graph.contains(displayId)) { + return mTopology.primaryDisplayId; + } + return displayId; +} + +bool InputDispatcher::DispatcherWindowInfo::areDisplaysConnected( + ui::LogicalDisplayId display1, ui::LogicalDisplayId display2) const { + return display1 == display2 || + (mTopology.graph.contains(display1) && mTopology.graph.contains(display2)); +} + std::string InputDispatcher::DispatcherWindowInfo::dumpDisplayAndWindowInfo() const { std::string dump; if (!mWindowHandlesByDisplay.empty()) { @@ -5316,11 +5222,40 @@ std::string InputDispatcher::DispatcherWindowInfo::dumpDisplayAndWindowInfo() co } else { dump += "Displays: <none>\n"; } + dump += StringPrintf("mMaximumObscuringOpacityForTouch: %f\n", + mMaximumObscuringOpacityForTouch); + dump += "DisplayTopologyGraph:\n"; + dump += addLinePrefix(mTopology.dump(), INDENT); + dump += "\n"; return dump; } -bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window, - const MotionEntry& motionEntry) const { +std::vector<ui::LogicalDisplayId> InputDispatcher::DispatcherWindowInfo::getConnectedDisplays( + ui::LogicalDisplayId displayId) const { + if (!mTopology.graph.contains(displayId)) { + return {displayId}; + } + + std::vector<ui::LogicalDisplayId> connectedDisplays; + for (auto it : mTopology.graph) { + connectedDisplays.push_back(it.first); + } + return connectedDisplays; +} + +sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWindowHandleOnDisplay( + const sp<IBinder>& windowHandleToken, ui::LogicalDisplayId displayId) const { + for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesForDisplay(displayId)) { + if (windowHandle->getToken() == windowHandleToken) { + return windowHandle; + } + } + return nullptr; +} + +bool InputDispatcher::DispatcherTouchState::canWindowReceiveMotion( + const sp<android::gui::WindowInfoHandle>& window, + const android::inputdispatcher::MotionEntry& motionEntry) const { const WindowInfo& info = *window->getInfo(); // Skip spy window targets that are not valid for targeted injection. @@ -5339,7 +5274,7 @@ bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& w return false; } - std::shared_ptr<Connection> connection = getConnectionLocked(window->getToken()); + std::shared_ptr<Connection> connection = mConnectionManager.getConnection(window->getToken()); if (connection == nullptr) { ALOGW("Not sending touch to %s because there's no corresponding connection", window->getName().c_str()); @@ -5353,8 +5288,9 @@ bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& w // Drop events that can't be trusted due to occlusion const auto [x, y] = resolveTouchedPosition(motionEntry); - TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y); - if (!isTouchTrustedLocked(occlusionInfo)) { + DispatcherWindowInfo::TouchOcclusionInfo occlusionInfo = + mWindowInfos.computeTouchOcclusionInfo(window, x, y); + if (!mWindowInfos.isTouchTrusted(occlusionInfo)) { if (DEBUG_TOUCH_OCCLUSION) { ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y); for (const auto& log : occlusionInfo.debugInfo) { @@ -5367,13 +5303,13 @@ bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& w } // Drop touch events if requested by input feature - if (shouldDropInput(motionEntry, window)) { + if (shouldDropInput(motionEntry, window, mWindowInfos)) { return false; } // Ignore touches if stylus is down anywhere on screen if (info.inputConfig.test(WindowInfo::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH) && - isStylusActiveInDisplay(info.displayId, mTouchStatesByDisplay)) { + isStylusActiveInDisplay(info.displayId)) { LOG(INFO) << "Dropping touch from " << window->getName() << " because stylus is active"; return false; } @@ -5402,7 +5338,7 @@ void InputDispatcher::updateWindowHandlesForDisplayLocked( std::vector<sp<WindowInfoHandle>> newHandles; for (const sp<WindowInfoHandle>& handle : windowInfoHandles) { const WindowInfo* info = handle->getInfo(); - if (getConnectionLocked(handle->getToken()) == nullptr) { + if (mConnectionManager.getConnection(handle->getToken()) == nullptr) { const bool noInputChannel = info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL); const bool canReceiveInput = @@ -5497,70 +5433,38 @@ void InputDispatcher::setInputWindowsLocked( onFocusChangedLocked(*changes, traceContext.getTracker(), removedFocusedWindowHandle); } - if (const auto& it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) { - TouchState& state = it->second; - for (size_t i = 0; i < state.windows.size();) { - TouchedWindow& touchedWindow = state.windows[i]; - if (mWindowInfos.isWindowPresent(touchedWindow.windowHandle)) { - i++; - continue; - } - LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName() - << " in display %" << displayId; - CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, - "touched window was removed", traceContext.getTracker()); - synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options); - // Since we are about to drop the touch, cancel the events for the wallpaper as - // well. - if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) && - touchedWindow.windowHandle->getInfo()->inputConfig.test( - gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) { - for (const DeviceId deviceId : touchedWindow.getTouchingDeviceIds()) { - if (const auto& ww = state.getWallpaperWindow(deviceId); ww != nullptr) { - options.deviceId = deviceId; - synthesizeCancelationEventsForWindowLocked(ww, options); - } - } - } - state.windows.erase(state.windows.begin() + i); - } - - // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We - // could just clear the state here. - if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId && - std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) == - windowHandles.end()) { - ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str()); - sendDropWindowCommandLocked(nullptr, 0, 0); - mDragState.reset(); + CancelationOptions pointerCancellationOptions(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, + "touched window was removed", + traceContext.getTracker()); + CancelationOptions hoverCancellationOptions(CancelationOptions::Mode::CANCEL_HOVER_EVENTS, + "WindowInfo changed", traceContext.getTracker()); + const std::list<DispatcherTouchState::CancellationArgs> cancellations = + mTouchStates.updateFromWindowInfo(displayId); + for (const auto& cancellationArgs : cancellations) { + switch (cancellationArgs.mode) { + case CancelationOptions::Mode::CANCEL_POINTER_EVENTS: + pointerCancellationOptions.deviceId = cancellationArgs.deviceId; + synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle, + pointerCancellationOptions); + break; + case CancelationOptions::Mode::CANCEL_HOVER_EVENTS: + hoverCancellationOptions.deviceId = cancellationArgs.deviceId; + synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle, + hoverCancellationOptions); + break; + default: + LOG_ALWAYS_FATAL("Unexpected cancellation Mode"); } } - // Check if the hovering should stop because the window is no longer eligible to receive it - // (for example, if the touchable region changed) - if (const auto& it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) { - TouchState& state = it->second; - for (TouchedWindow& touchedWindow : state.windows) { - std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf( - [this, displayId, &touchedWindow](const PointerProperties& properties, float x, - float y) REQUIRES(mLock) { - const bool isStylus = properties.toolType == ToolType::STYLUS; - const ui::Transform displayTransform = - mWindowInfos.getDisplayTransform(displayId); - const bool stillAcceptsTouch = - windowAcceptsTouchAt(*touchedWindow.windowHandle->getInfo(), - displayId, x, y, isStylus, displayTransform); - return !stillAcceptsTouch; - }); - - for (DeviceId deviceId : erasedDevices) { - CancelationOptions options(CancelationOptions::Mode::CANCEL_HOVER_EVENTS, - "WindowInfo changed", - traceContext.getTracker()); - options.deviceId = deviceId; - synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options); - } - } + // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We + // could just clear the state here. + if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId && + std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) == + windowHandles.end()) { + ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str()); + sendDropWindowCommandLocked(nullptr, 0, 0); + mDragState.reset(); } // Release information for windows that are no longer present. @@ -5569,21 +5473,86 @@ void InputDispatcher::setInputWindowsLocked( // which might not happen until the next GC. for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) { if (!mWindowInfos.isWindowPresent(oldWindowHandle)) { - if (DEBUG_FOCUS) { - ALOGD("Window went away: %s", oldWindowHandle->getName().c_str()); - } + LOG_IF(INFO, DEBUG_FOCUS) << "Window went away: " << oldWindowHandle->getName(); oldWindowHandle->releaseChannel(); } } } +std::list<InputDispatcher::DispatcherTouchState::CancellationArgs> +InputDispatcher::DispatcherTouchState::updateFromWindowInfo(ui::LogicalDisplayId displayId) { + std::list<CancellationArgs> cancellations; + forTouchAndCursorStatesOnDisplay(displayId, [&](TouchState& state) { + cancellations.splice(cancellations.end(), + eraseRemovedWindowsFromWindowInfo(state, displayId)); + cancellations.splice(cancellations.end(), + updateHoveringStateFromWindowInfo(state, displayId)); + return false; + }); + return cancellations; +} + +std::list<InputDispatcher::DispatcherTouchState::CancellationArgs> +InputDispatcher::DispatcherTouchState::eraseRemovedWindowsFromWindowInfo( + TouchState& state, ui::LogicalDisplayId displayId) { + std::list<CancellationArgs> cancellations; + for (auto it = state.windows.begin(); it != state.windows.end();) { + TouchedWindow& touchedWindow = *it; + if (mWindowInfos.isWindowPresent(touchedWindow.windowHandle)) { + it++; + continue; + } + LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName() + << " in display %" << displayId; + cancellations.emplace_back(touchedWindow.windowHandle, + CancelationOptions::Mode::CANCEL_POINTER_EVENTS); + // Since we are about to drop the touch, cancel the events for the wallpaper as well. + if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) && + touchedWindow.windowHandle->getInfo()->inputConfig.test( + gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) { + for (const DeviceId deviceId : touchedWindow.getTouchingDeviceIds()) { + if (const auto& ww = state.getWallpaperWindow(deviceId); ww != nullptr) { + cancellations.emplace_back(ww, CancelationOptions::Mode::CANCEL_POINTER_EVENTS, + deviceId); + } + } + } + it = state.windows.erase(it); + } + return cancellations; +} + +std::list<InputDispatcher::DispatcherTouchState::CancellationArgs> +InputDispatcher::DispatcherTouchState::updateHoveringStateFromWindowInfo( + TouchState& state, ui::LogicalDisplayId displayId) { + std::list<CancellationArgs> cancellations; + // Check if the hovering should stop because the window is no longer eligible to receive it + // (for example, if the touchable region changed) + ui::Transform displayTransform = mWindowInfos.getDisplayTransform(displayId); + for (TouchedWindow& touchedWindow : state.windows) { + std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf( + [&](const PointerProperties& properties, float x, float y) { + const bool isStylus = properties.toolType == ToolType::STYLUS; + const bool stillAcceptsTouch = + windowAcceptsTouchAt(*touchedWindow.windowHandle->getInfo(), displayId, + x, y, isStylus, displayTransform); + return !stillAcceptsTouch; + }); + + for (DeviceId deviceId : erasedDevices) { + cancellations.emplace_back(touchedWindow.windowHandle, + CancelationOptions::Mode::CANCEL_HOVER_EVENTS, deviceId); + } + } + return cancellations; +} + void InputDispatcher::setFocusedApplication( ui::LogicalDisplayId displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) { - if (DEBUG_FOCUS) { - ALOGD("setFocusedApplication displayId=%s %s", displayId.toString().c_str(), - inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>"); - } + LOG_IF(INFO, DEBUG_FOCUS) << "setFocusedApplication displayId=" << displayId.toString() << " " + << (inputApplicationHandle ? inputApplicationHandle->getName() + : "<nullptr>"); { // acquire lock std::scoped_lock _l(mLock); setFocusedApplicationLocked(displayId, inputApplicationHandle); @@ -5633,9 +5602,7 @@ void InputDispatcher::setMinTimeBetweenUserActivityPokes(std::chrono::millisecon * display. The display-specified events won't be affected. */ void InputDispatcher::setFocusedDisplay(ui::LogicalDisplayId displayId) { - if (DEBUG_FOCUS) { - ALOGD("setFocusedDisplay displayId=%s", displayId.toString().c_str()); - } + LOG_IF(INFO, DEBUG_FOCUS) << "setFocusedDisplay displayId=" << displayId.toString(); { // acquire lock std::scoped_lock _l(mLock); ScopedSyntheticEventTracer traceContext(mTracer); @@ -5689,9 +5656,8 @@ void InputDispatcher::setFocusedDisplay(ui::LogicalDisplayId displayId) { } void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) { - if (DEBUG_FOCUS) { - ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen); - } + LOG_IF(INFO, DEBUG_FOCUS) << "setInputDispatchMode: enabled=" << enabled + << ", frozen=" << frozen; bool changed; { // acquire lock @@ -5721,9 +5687,7 @@ void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) { } void InputDispatcher::setInputFilterEnabled(bool enabled) { - if (DEBUG_FOCUS) { - ALOGD("setInputFilterEnabled: enabled=%d", enabled); - } + LOG_IF(INFO, DEBUG_FOCUS) << "setInputFilterEnabled: enabled=" << enabled; { // acquire lock std::scoped_lock _l(mLock); @@ -5745,14 +5709,16 @@ bool InputDispatcher::setInTouchMode(bool inTouchMode, gui::Pid pid, gui::Uid ui bool needWake = false; { std::scoped_lock lock(mLock); - ALOGD_IF(DEBUG_TOUCH_MODE, - "Request to change touch mode to %s (calling pid=%s, uid=%s, " - "hasPermission=%s, target displayId=%s, mTouchModePerDisplay[displayId]=%s)", - toString(inTouchMode), pid.toString().c_str(), uid.toString().c_str(), - toString(hasPermission), displayId.toString().c_str(), - mTouchModePerDisplay.count(displayId) == 0 - ? "not set" - : std::to_string(mTouchModePerDisplay[displayId]).c_str()); + LOG_IF(INFO, DEBUG_TOUCH_MODE) + << "Request to change touch mode to " << toString(inTouchMode) + << " (calling pid=" << pid.toString() << ", uid=" << uid.toString() + << ", hasPermission=" << toString(hasPermission) + << ", target displayId=" << displayId.toString() + << ", mTouchModePerDisplay[displayId]=" + << (mTouchModePerDisplay.count(displayId) == 0 + ? "not set" + : std::to_string(mTouchModePerDisplay[displayId])) + << ")"; auto touchModeIt = mTouchModePerDisplay.find(displayId); if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) { @@ -5798,113 +5764,46 @@ bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid) } void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) { - if (opacity < 0 || opacity > 1) { - LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1"); - return; - } - std::scoped_lock lock(mLock); - mMaximumObscuringOpacityForTouch = opacity; -} - -std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId> -InputDispatcher::findTouchStateWindowAndDisplay( - const sp<IBinder>& token, - const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) { - for (auto& [displayId, state] : touchStatesByDisplay) { - for (const TouchedWindow& w : state.windows) { - if (w.windowHandle->getToken() == token) { - return std::make_tuple(&state, &w, displayId); - } - } - } - return std::make_tuple(nullptr, nullptr, ui::LogicalDisplayId::DEFAULT); -} - -std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId> -InputDispatcher::findTouchStateWindowAndDisplay( - const sp<IBinder>& token, - std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) { - auto [constTouchState, constTouchedWindow, displayId] = InputDispatcher:: - findTouchStateWindowAndDisplay(token, - const_cast<const std::unordered_map<ui::LogicalDisplayId, - TouchState>&>( - touchStatesByDisplay)); - - return std::make_tuple(const_cast<TouchState*>(constTouchState), - const_cast<TouchedWindow*>(constTouchedWindow), displayId); -} - -bool InputDispatcher::windowHasTouchingPointers( - const sp<WindowInfoHandle>& windowHandle, DeviceId deviceId, - const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) { - const auto& [touchState, touchedWindow, _] = - findTouchStateWindowAndDisplay(windowHandle->getToken(), touchStatesByDisplay); - if (touchState == nullptr) { - // No touching pointers at all - return false; - } - return touchState->hasTouchingPointers(deviceId); + mWindowInfos.setMaximumObscuringOpacityForTouch(opacity); } bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken, bool isDragDrop) { if (fromToken == toToken) { - if (DEBUG_FOCUS) { - ALOGD("Trivial transfer to same window."); - } + LOG_IF(INFO, DEBUG_FOCUS) << "Trivial transfer to same window."; return true; } { // acquire lock std::scoped_lock _l(mLock); - // Find the target touch state and touched window by fromToken. - auto [state, touchedWindow, displayId] = - findTouchStateWindowAndDisplay(fromToken, mTouchStatesByDisplay); + ScopedSyntheticEventTracer traceContext(mTracer); + CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, + "transferring touch from this window to another window", + traceContext.getTracker()); - if (state == nullptr || touchedWindow == nullptr) { - ALOGD("Touch transfer failed because from window is not being touched."); + auto result = mTouchStates.transferTouchGesture(fromToken, toToken); + if (!result.has_value()) { return false; } - std::set<DeviceId> deviceIds = touchedWindow->getTouchingDeviceIds(); - if (deviceIds.size() != 1) { - LOG(INFO) << "Can't transfer touch. Currently touching devices: " << dumpSet(deviceIds) - << " for window: " << touchedWindow->dump(); - return false; - } - const DeviceId deviceId = *deviceIds.begin(); - const sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle; - const sp<WindowInfoHandle> toWindowHandle = - mWindowInfos.findWindowHandle(toToken, displayId); - if (!toWindowHandle) { - ALOGW("Cannot transfer touch because the transfer target window was not found."); - return false; - } + const auto& [toWindowHandle, deviceId, pointers, cancellations, pointerDowns] = + result.value(); - if (DEBUG_FOCUS) { - ALOGD("%s: fromWindowHandle=%s, toWindowHandle=%s", __func__, - touchedWindow->windowHandle->getName().c_str(), - toWindowHandle->getName().c_str()); + for (const auto& cancellationArgs : cancellations) { + LOG_ALWAYS_FATAL_IF(cancellationArgs.mode != + CancelationOptions::Mode::CANCEL_POINTER_EVENTS); + LOG_ALWAYS_FATAL_IF(cancellationArgs.deviceId.has_value()); + synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle, options); } - // Erase old window. - ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags; - std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId); - state->removeWindowByToken(fromToken); - - // Add new window. - nsecs_t downTimeInTarget = now(); - ftl::Flags<InputTarget::Flags> newTargetFlags = - oldTargetFlags & (InputTarget::Flags::SPLIT); - if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) { - newTargetFlags |= InputTarget::Flags::FOREGROUND; + for (const auto& pointerDownArgs : pointerDowns) { + synthesizePointerDownEventsForConnectionLocked(pointerDownArgs.downTimeInTarget, + pointerDownArgs.connection, + pointerDownArgs.targetFlags, + traceContext.getTracker()); } - // Transferring touch focus using this API should not effect the focused window. - newTargetFlags |= InputTarget::Flags::NO_FOCUS_CHANGE; - state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags, - deviceId, pointers, downTimeInTarget); // Store the dragging window. if (isDragDrop) { @@ -5917,30 +5816,6 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s const size_t id = pointers.begin()->id; mDragState = std::make_unique<DragState>(toWindowHandle, deviceId, id); } - - // Synthesize cancel for old window and down for new window. - ScopedSyntheticEventTracer traceContext(mTracer); - std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken); - std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken); - if (fromConnection != nullptr && toConnection != nullptr) { - fromConnection->inputState.mergePointerStateTo(toConnection->inputState); - CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, - "transferring touch from this window to another window", - traceContext.getTracker()); - synthesizeCancelationEventsForWindowLocked(fromWindowHandle, options, fromConnection); - - // Check if the wallpaper window should deliver the corresponding event. - transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle, - *state, deviceId, pointers, traceContext.getTracker()); - - // Because new window may have a wallpaper window, it will merge input state from it - // parent window, after this the firstNewPointerIdx in input state will be reset, then - // it will cause new move event be thought inconsistent, so we should synthesize the - // down event after it reset. - synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection, - newTargetFlags, - traceContext.getTracker()); - } } // release lock // Wake up poll loop since it may need to make new input dispatching choices. @@ -5948,34 +5823,110 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s return true; } +std::optional<std::tuple<sp<gui::WindowInfoHandle>, DeviceId, std::vector<PointerProperties>, + std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>, + std::list<InputDispatcher::DispatcherTouchState::PointerDownArgs>>> +InputDispatcher::DispatcherTouchState::transferTouchGesture(const sp<android::IBinder>& fromToken, + const sp<android::IBinder>& toToken) { + // Find the target touch state and touched window by fromToken. + auto touchStateWindowAndDisplay = findTouchStateWindowAndDisplay(fromToken); + if (!touchStateWindowAndDisplay.has_value()) { + ALOGD("Touch transfer failed because from window is not being touched."); + return std::nullopt; + } + + auto [state, touchedWindow, displayId] = touchStateWindowAndDisplay.value(); + std::set<DeviceId> deviceIds = touchedWindow.getTouchingDeviceIds(); + if (deviceIds.size() != 1) { + LOG(INFO) << "Can't transfer touch. Currently touching devices: " + << dumpContainer(deviceIds) << " for window: " << touchedWindow.dump(); + return std::nullopt; + } + const DeviceId deviceId = *deviceIds.begin(); + + const sp<WindowInfoHandle> fromWindowHandle = touchedWindow.windowHandle; + // TouchState displayId may not be same as window displayId, we need to lookup for toToken on + // all connected displays. + const sp<WindowInfoHandle> toWindowHandle = + mWindowInfos.findWindowHandleOnConnectedDisplays(toToken, displayId); + if (!toWindowHandle) { + ALOGW("Cannot transfer touch because the transfer target window was not found."); + return std::nullopt; + } + + LOG_IF(INFO, DEBUG_FOCUS) << __func__ << ": fromWindowHandle=" << fromWindowHandle->getName() + << ", toWindowHandle=" << toWindowHandle->getName(); + + // Erase old window. + ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow.targetFlags; + std::vector<PointerProperties> pointers = touchedWindow.getTouchingPointers(deviceId); + state.removeWindowByToken(fromToken); + + // Add new window. + nsecs_t downTimeInTarget = now(); + ftl::Flags<InputTarget::Flags> newTargetFlags = oldTargetFlags & (InputTarget::Flags::SPLIT); + if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) { + newTargetFlags |= InputTarget::Flags::FOREGROUND; + } + // Transferring touch focus using this API should not effect the focused window. + newTargetFlags |= InputTarget::Flags::NO_FOCUS_CHANGE; + state.addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags, + deviceId, pointers, downTimeInTarget); + + // Synthesize cancel for old window and down for new window. + std::shared_ptr<Connection> fromConnection = mConnectionManager.getConnection(fromToken); + std::shared_ptr<Connection> toConnection = mConnectionManager.getConnection(toToken); + std::list<CancellationArgs> cancellations; + std::list<PointerDownArgs> pointerDowns; + if (fromConnection != nullptr && toConnection != nullptr) { + fromConnection->inputState.mergePointerStateTo(toConnection->inputState); + cancellations.emplace_back(fromWindowHandle, + CancelationOptions::Mode::CANCEL_POINTER_EVENTS); + + // Check if the wallpaper window should deliver the corresponding event. + auto [wallpaperCancellations, wallpaperPointerDowns] = + transferWallpaperTouch(fromWindowHandle, toWindowHandle, state, deviceId, pointers, + oldTargetFlags, newTargetFlags); + + cancellations.splice(cancellations.end(), wallpaperCancellations); + pointerDowns.splice(pointerDowns.end(), wallpaperPointerDowns); + + // Because new window may have a wallpaper window, it will merge input state from it + // parent window, after this the firstNewPointerIdx in input state will be reset, then + // it will cause new move event be thought inconsistent, so we should synthesize the + // down event after it reset. + pointerDowns.emplace_back(downTimeInTarget, toConnection, newTargetFlags); + } + + return std::make_tuple(toWindowHandle, deviceId, pointers, cancellations, pointerDowns); +} + /** * Get the touched foreground window on the given display. * Return null if there are no windows touched on that display, or if more than one foreground * window is being touched. */ -sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindow( - const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay, - ui::LogicalDisplayId displayId) { - const auto stateIt = touchStatesByDisplay.find(displayId); - if (stateIt == touchStatesByDisplay.end()) { - ALOGI("No touch state on display %s", displayId.toString().c_str()); - return nullptr; - } - - const TouchState& state = stateIt->second; +sp<WindowInfoHandle> InputDispatcher::DispatcherTouchState::findTouchedForegroundWindow( + ui::LogicalDisplayId displayId) const { sp<WindowInfoHandle> touchedForegroundWindow; - // If multiple foreground windows are touched, return nullptr - for (const TouchedWindow& window : state.windows) { - if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) { - if (touchedForegroundWindow != nullptr) { - ALOGI("Two or more foreground windows: %s and %s", - touchedForegroundWindow->getName().c_str(), - window.windowHandle->getName().c_str()); - return nullptr; + forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) { + // If multiple foreground windows are touched, return nullptr + for (const TouchedWindow& window : state.windows) { + if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) { + if (touchedForegroundWindow != nullptr) { + ALOGI("Two or more foreground windows: %s and %s", + touchedForegroundWindow->getName().c_str(), + window.windowHandle->getName().c_str()); + touchedForegroundWindow = nullptr; + return true; + } + touchedForegroundWindow = window.windowHandle; } - touchedForegroundWindow = window.windowHandle; } - } + return false; + }); + ALOGI_IF(touchedForegroundWindow == nullptr, + "No touch state or no touched foreground window on display %d", displayId.val()); return touchedForegroundWindow; } @@ -5993,7 +5944,7 @@ bool InputDispatcher::transferTouchOnDisplay(const sp<IBinder>& destChannelToken return false; } - sp<WindowInfoHandle> from = findTouchedForegroundWindow(mTouchStatesByDisplay, displayId); + sp<WindowInfoHandle> from = mTouchStates.findTouchedForegroundWindow(displayId); if (from == nullptr) { ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get()); return false; @@ -6006,9 +5957,7 @@ bool InputDispatcher::transferTouchOnDisplay(const sp<IBinder>& destChannelToken } void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { - if (DEBUG_FOCUS) { - ALOGD("Resetting and dropping all events (%s).", reason); - } + LOG_IF(INFO, DEBUG_FOCUS) << "Resetting and dropping all events (" << reason << ")."; ScopedSyntheticEventTracer traceContext(mTracer); CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason, @@ -6021,7 +5970,7 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { resetNoFocusedWindowTimeoutLocked(); mAnrTracker.clear(); - mTouchStatesByDisplay.clear(); + mTouchStates.clear(); } void InputDispatcher::logDispatchStateLocked() const { @@ -6079,15 +6028,7 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const { dump += mFocusResolver.dump(); dump += dumpPointerCaptureStateLocked(); - if (!mTouchStatesByDisplay.empty()) { - dump += StringPrintf(INDENT "TouchStatesByDisplay:\n"); - for (const auto& [displayId, state] : mTouchStatesByDisplay) { - std::string touchStateDump = addLinePrefix(state.dump(), INDENT2); - dump += INDENT2 + displayId.toString() + " : " + touchStateDump; - } - } else { - dump += INDENT "TouchStates: <no displays touched>\n"; - } + dump += addLinePrefix(mTouchStates.dump(), INDENT); if (mDragState) { dump += StringPrintf(INDENT "DragState:\n"); @@ -6096,18 +6037,10 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const { dump += addLinePrefix(mWindowInfos.dumpDisplayAndWindowInfo(), INDENT); - if (!mGlobalMonitorsByDisplay.empty()) { - for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) { - dump += StringPrintf(INDENT "Global monitors on display %s:\n", - displayId.toString().c_str()); - dumpMonitors(dump, monitors); - } - } else { - dump += INDENT "Global Monitors: <none>\n"; - } - const nsecs_t currentTime = now(); + dump += addLinePrefix(mConnectionManager.dump(currentTime), INDENT); + // Dump recently dispatched or dropped events from oldest to newest. if (!mRecentQueue.empty()) { dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size()); @@ -6149,37 +6082,6 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const { dump += INDENT "CommandQueue: <empty>\n"; } - if (!mConnectionsByToken.empty()) { - dump += INDENT "Connections:\n"; - for (const auto& [token, connection] : mConnectionsByToken) { - dump += StringPrintf(INDENT2 "%i: channelName='%s', " - "status=%s, monitor=%s, responsive=%s\n", - connection->inputPublisher.getChannel().getFd(), - connection->getInputChannelName().c_str(), - ftl::enum_string(connection->status).c_str(), - toString(connection->monitor), toString(connection->responsive)); - - if (!connection->outboundQueue.empty()) { - dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n", - connection->outboundQueue.size()); - dump += dumpQueue(connection->outboundQueue, currentTime); - } - - if (!connection->waitQueue.empty()) { - dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n", - connection->waitQueue.size()); - dump += dumpQueue(connection->waitQueue, currentTime); - } - std::string inputStateDump = streamableToString(connection->inputState); - if (!inputStateDump.empty()) { - dump += INDENT3 "InputState: "; - dump += inputStateDump + "\n"; - } - } - } else { - dump += INDENT "Connections: <none>\n"; - } - if (!mTouchModePerDisplay.empty()) { dump += INDENT "TouchModePerDisplay:\n"; for (const auto& [displayId, touchMode] : mTouchModePerDisplay) { @@ -6200,16 +6102,6 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const { dump += mTracer == nullptr ? "Disabled" : "Enabled"; } -void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const { - const size_t numMonitors = monitors.size(); - for (size_t i = 0; i < numMonitors; i++) { - const Monitor& monitor = monitors[i]; - const std::shared_ptr<Connection>& connection = monitor.connection; - dump += StringPrintf(INDENT2 "%zu: '%s', ", i, connection->getInputChannelName().c_str()); - dump += "\n"; - } -} - class LooperEventCallback : public LooperCallback { public: LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {} @@ -6220,9 +6112,7 @@ private: }; Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) { - if (DEBUG_CHANNEL_CREATION) { - ALOGD("channel '%s' ~ createInputChannel", name.c_str()); - } + LOG_IF(INFO, DEBUG_CHANNEL_CREATION) << "channel '" << name << "' ~ createInputChannel"; std::unique_ptr<InputChannel> serverChannel; std::unique_ptr<InputChannel> clientChannel; @@ -6235,21 +6125,10 @@ Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const { // acquire lock std::scoped_lock _l(mLock); const sp<IBinder>& token = serverChannel->getConnectionToken(); - const int fd = serverChannel->getFd(); - std::shared_ptr<Connection> connection = - std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false, - mIdGenerator); - - auto [_, inserted] = mConnectionsByToken.try_emplace(token, connection); - if (!inserted) { - ALOGE("Created a new connection, but the token %p is already known", token.get()); - } - std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback, this, std::placeholders::_1, token); - mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback), - nullptr); + mConnectionManager.createConnection(std::move(serverChannel), mIdGenerator, callback); } // release lock // Wake the looper because some connections have changed. @@ -6275,23 +6154,11 @@ Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor( } const sp<IBinder>& token = serverChannel->getConnectionToken(); - const int fd = serverChannel->getFd(); - std::shared_ptr<Connection> connection = - std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/true, - mIdGenerator); - - auto [_, inserted] = mConnectionsByToken.emplace(token, connection); - if (!inserted) { - ALOGE("Created a new connection, but the token %p is already known", token.get()); - } - std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback, this, std::placeholders::_1, token); - mGlobalMonitorsByDisplay[displayId].emplace_back(connection, pid); - - mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback), - nullptr); + mConnectionManager.createGlobalInputMonitor(displayId, std::move(serverChannel), + mIdGenerator, pid, callback); } // Wake the looper because some connections have changed. @@ -6302,8 +6169,14 @@ Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor( status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) { { // acquire lock std::scoped_lock _l(mLock); + std::shared_ptr<Connection> connection = mConnectionManager.getConnection(connectionToken); + if (connection == nullptr) { + // Connection can be removed via socket hang up or an explicit call to + // 'removeInputChannel' + return BAD_VALUE; + } - status_t status = removeInputChannelLocked(connectionToken, /*notify=*/false); + status_t status = removeInputChannelLocked(connection, /*notify=*/false); if (status) { return status; } @@ -6315,30 +6188,18 @@ status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) return OK; } -status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken, +status_t InputDispatcher::removeInputChannelLocked(const std::shared_ptr<Connection>& connection, bool notify) { - std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken); - if (connection == nullptr) { - // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel' - return BAD_VALUE; - } - - removeConnectionLocked(connection); - - if (connection->monitor) { - removeMonitorChannelLocked(connectionToken); - } - - mLooper->removeFd(connection->inputPublisher.getChannel().getFd()); + LOG_ALWAYS_FATAL_IF(connection == nullptr); + abortBrokenDispatchCycleLocked(connection, notify); - nsecs_t currentTime = now(); - abortBrokenDispatchCycleLocked(currentTime, connection, notify); + mAnrTracker.eraseToken(connection->getToken()); + mConnectionManager.removeConnection(connection); - connection->status = Connection::Status::ZOMBIE; return OK; } -void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) { +void InputDispatcher::ConnectionManager::removeMonitorChannel(const sp<IBinder>& connectionToken) { for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) { auto& [displayId, monitors] = *it; std::erase_if(monitors, [connectionToken](const Monitor& monitor) { @@ -6359,50 +6220,70 @@ status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) { } status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) { - const std::shared_ptr<Connection> requestingConnection = getConnectionLocked(token); + const std::shared_ptr<Connection> requestingConnection = + mConnectionManager.getConnection(token); if (!requestingConnection) { LOG(WARNING) << "Attempted to pilfer pointers from an un-registered channel or invalid token"; return BAD_VALUE; } - auto [statePtr, windowPtr, displayId] = - findTouchStateWindowAndDisplay(token, mTouchStatesByDisplay); - if (statePtr == nullptr || windowPtr == nullptr) { + const auto result = mTouchStates.pilferPointers(token, *requestingConnection); + if (!result.ok()) { + return result.error().code(); + } + + ScopedSyntheticEventTracer traceContext(mTracer); + CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, + "input channel stole pointer stream", traceContext.getTracker()); + const auto cancellations = *result; + for (const auto& cancellationArgs : cancellations) { + LOG_ALWAYS_FATAL_IF(cancellationArgs.mode != + CancelationOptions::Mode::CANCEL_POINTER_EVENTS); + options.displayId = cancellationArgs.displayId; + options.deviceId = cancellationArgs.deviceId; + options.pointerIds = cancellationArgs.pointerIds; + synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle, options); + } + return OK; +} + +base::Result<std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>, status_t> +InputDispatcher::DispatcherTouchState::pilferPointers(const sp<IBinder>& token, + const Connection& requestingConnection) { + auto touchStateWindowAndDisplay = findTouchStateWindowAndDisplay(token); + if (!touchStateWindowAndDisplay.has_value()) { LOG(WARNING) << "Attempted to pilfer points from a channel without any on-going pointer streams." " Ignoring."; - return BAD_VALUE; + return Error(BAD_VALUE); } - std::set<int32_t> deviceIds = windowPtr->getTouchingDeviceIds(); + + auto [state, window, displayId] = touchStateWindowAndDisplay.value(); + + std::set<int32_t> deviceIds = window.getTouchingDeviceIds(); if (deviceIds.empty()) { - LOG(WARNING) << "Can't pilfer: no touching devices in window: " << windowPtr->dump(); - return BAD_VALUE; + LOG(WARNING) << "Can't pilfer: no touching devices in window: " << window.dump(); + return Error(BAD_VALUE); } - ScopedSyntheticEventTracer traceContext(mTracer); + std::list<CancellationArgs> cancellations; for (const DeviceId deviceId : deviceIds) { - TouchState& state = *statePtr; - TouchedWindow& window = *windowPtr; // Send cancel events to all the input channels we're stealing from. - CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, - "input channel stole pointer stream", traceContext.getTracker()); - options.deviceId = deviceId; - options.displayId = displayId; std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId); std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers); - options.pointerIds = pointerIds; - std::string canceledWindows; for (const TouchedWindow& w : state.windows) { if (w.windowHandle->getToken() != token) { - synthesizeCancelationEventsForWindowLocked(w.windowHandle, options); + cancellations.emplace_back(w.windowHandle, + CancelationOptions::Mode::CANCEL_POINTER_EVENTS, + deviceId, displayId, pointerIds); canceledWindows += canceledWindows.empty() ? "[" : ", "; canceledWindows += w.windowHandle->getName(); } } canceledWindows += canceledWindows.empty() ? "[]" : "]"; - LOG(INFO) << "Channel " << requestingConnection->getInputChannelName() + LOG(INFO) << "Channel " << requestingConnection.getInputChannelName() << " is stealing input gesture for device " << deviceId << " from " << canceledWindows; @@ -6412,7 +6293,7 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) { state.cancelPointersForWindowsExcept(deviceId, pointerIds, token); } - return OK; + return cancellations; } void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) { @@ -6466,7 +6347,8 @@ void InputDispatcher::setDisplayEligibilityForPointerCapture(ui::LogicalDisplayI } // release lock } -std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) { +std::optional<gui::Pid> InputDispatcher::ConnectionManager::findMonitorPidByToken( + const sp<IBinder>& token) const { for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) { for (const Monitor& monitor : monitors) { if (monitor.connection->getToken() == token) { @@ -6477,7 +6359,7 @@ std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IB return std::nullopt; } -std::shared_ptr<Connection> InputDispatcher::getConnectionLocked( +std::shared_ptr<Connection> InputDispatcher::ConnectionManager::getConnection( const sp<IBinder>& inputConnectionToken) const { if (inputConnectionToken == nullptr) { return nullptr; @@ -6492,19 +6374,6 @@ std::shared_ptr<Connection> InputDispatcher::getConnectionLocked( return nullptr; } -std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const { - std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken); - if (connection == nullptr) { - return "<nullptr>"; - } - return connection->getInputChannelName(); -} - -void InputDispatcher::removeConnectionLocked(const std::shared_ptr<Connection>& connection) { - mAnrTracker.eraseToken(connection->getToken()); - mConnectionsByToken.erase(connection->getToken()); -} - void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime, const std::shared_ptr<Connection>& connection, uint32_t seq, bool handled, @@ -6567,9 +6436,8 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime, createInputTarget(connection, windowHandle, InputTarget::DispatchMode::AS_IS, dispatchEntry->targetFlags, - mWindowInfos.getDisplayTransform( - windowHandle->getInfo() - ->displayId), + mWindowInfos.getRawTransform( + *windowHandle->getInfo()), downTime)); } } @@ -6730,7 +6598,7 @@ void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& conn if (connection.monitor) { ALOGW("Monitor %s is unresponsive: %s", connection.getInputChannelName().c_str(), reason.c_str()); - pid = findMonitorPidByTokenLocked(connectionToken); + pid = mConnectionManager.findMonitorPidByToken(connectionToken); } else { // The connection is a window ALOGW("Window %s is unresponsive: %s", connection.getInputChannelName().c_str(), @@ -6750,7 +6618,7 @@ void InputDispatcher::processConnectionResponsiveLocked(const Connection& connec const sp<IBinder>& connectionToken = connection.getToken(); std::optional<gui::Pid> pid; if (connection.monitor) { - pid = findMonitorPidByTokenLocked(connectionToken); + pid = mConnectionManager.findMonitorPidByToken(connectionToken); } else { // The connection is a window const sp<WindowInfoHandle> handle = mWindowInfos.findWindowHandle(connectionToken); @@ -6795,12 +6663,11 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl // then cancel the associated fallback key, if any. if (fallbackKeyCode) { // Dispatch the unhandled key to the policy with the cancel flag. - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("Unhandled key event: Asking policy to cancel fallback action. " - "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", - keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, - keyEntry.policyFlags); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "Unhandled key event: Asking policy to cancel fallback action. keyCode=" + << keyEntry.keyCode << ", action=" << keyEntry.action + << ", repeatCount=" << keyEntry.repeatCount << ", policyFlags=0x" << std::hex + << keyEntry.policyFlags; KeyEvent event = createKeyEvent(keyEntry); event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED); @@ -6837,21 +6704,22 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl // Then ask the policy what to do with it. bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0; if (!fallbackKeyCode && !initialDown) { - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("Unhandled key event: Skipping unhandled key event processing " - "since this is not an initial down. " - "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", - originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "Unhandled key event: Skipping unhandled key event processing since this is " + "not an initial down. keyCode=" + << originalKeyCode << ", action=" << keyEntry.action + << ", repeatCount=" << keyEntry.repeatCount << ", policyFlags=0x" << std::hex + << keyEntry.policyFlags; return {}; } // Dispatch the unhandled key to the policy. - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("Unhandled key event: Asking policy to perform fallback action. " - "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", - keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "Unhandled key event: Asking policy to perform fallback action. keyCode=" + << keyEntry.keyCode << ", action=" << keyEntry.action + << ", repeatCount=" << keyEntry.repeatCount << ", policyFlags=0x" << std::hex + << keyEntry.policyFlags; + ; KeyEvent event = createKeyEvent(keyEntry); mLock.unlock(); @@ -6948,16 +6816,13 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl newEntry->traceTracker = mTracer->traceDerivedEvent(*newEntry, *keyEntry.traceTracker); } - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("Unhandled key event: Dispatching fallback key. " - "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x", - originalKeyCode, *fallbackKeyCode, keyEntry.metaState); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) + << "Unhandled key event: Dispatching fallback key. originalKeyCode=" + << originalKeyCode << ", fallbackKeyCode=" << *fallbackKeyCode + << ", fallbackMetaState=0x" << std::hex << keyEntry.metaState; return newEntry; } else { - if (DEBUG_OUTBOUND_EVENT_DETAILS) { - ALOGD("Unhandled key event: No fallback key."); - } + LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) << "Unhandled key event: No fallback key."; // Report the key as unhandled, since there is no fallback key. mReporter->reportUnhandledKey(keyEntry.id); @@ -7098,7 +6963,7 @@ void InputDispatcher::disablePointerCaptureForcedLocked() { return; } - ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus."); + LOG_IF(INFO, DEBUG_FOCUS) << "Disabling Pointer Capture because the window lost focus."; if (mCurrentPointerCaptureRequest.isEnable()) { setPointerCaptureLocked(nullptr); @@ -7168,13 +7033,6 @@ void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) for (const auto& info : update.windowInfos) { handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>()); handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info)); - if (input_flags::split_all_touches()) { - handlesPerDisplay[info.displayId] - .back() - ->editInfo() - ->setInputConfig(android::gui::WindowInfo::InputConfig::PREVENT_SPLITTING, - false); - } } { // acquire lock @@ -7202,12 +7060,13 @@ void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) mLooper->wake(); } -bool InputDispatcher::shouldDropInput( - const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const { +bool InputDispatcher::shouldDropInput(const EventEntry& entry, + const sp<WindowInfoHandle>& windowHandle, + const DispatcherWindowInfo& windowInfos) { if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) || (windowHandle->getInfo()->inputConfig.test( WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) && - isWindowObscuredLocked(windowHandle))) { + windowInfos.isWindowObscured(windowHandle))) { ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on " "display %s.", ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(), @@ -7232,7 +7091,7 @@ void InputDispatcher::cancelCurrentTouch() { "cancel current touch", traceContext.getTracker()); synthesizeCancelationEventsForAllConnectionsLocked(options); - mTouchStatesByDisplay.clear(); + mTouchStates.clear(); } // Wake up poll loop since there might be work to do. mLooper->wake(); @@ -7243,11 +7102,10 @@ void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanosecon mMonitorDispatchingTimeout = timeout; } -void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags, - const sp<WindowInfoHandle>& oldWindowHandle, - const sp<WindowInfoHandle>& newWindowHandle, - TouchState& state, const MotionEntry& entry, - std::vector<InputTarget>& targets) const { +void InputDispatcher::DispatcherTouchState::slipWallpaperTouch( + ftl::Flags<InputTarget::Flags> targetFlags, const sp<WindowInfoHandle>& oldWindowHandle, + const sp<WindowInfoHandle>& newWindowHandle, TouchState& state, const MotionEntry& entry, + std::vector<InputTarget>& targets, std::function<void()> dump) { LOG_IF(FATAL, entry.getPointerCount() != 1) << "Entry not eligible for slip: " << entry; const DeviceId deviceId = entry.deviceId; const PointerProperties& pointerProperties = entry.pointerProperties[0]; @@ -7260,16 +7118,17 @@ void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFl const sp<WindowInfoHandle> oldWallpaper = oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr; const sp<WindowInfoHandle> newWallpaper = - newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr; + newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(newWindowHandle) : nullptr; if (oldWallpaper == newWallpaper) { return; } if (oldWallpaper != nullptr) { const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper); - addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT, - oldTouchedWindow.targetFlags, getPointerIds(pointers), - oldTouchedWindow.getDownTimeInTarget(deviceId), targets); + addPointerWindowTarget(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT, + oldTouchedWindow.targetFlags, getPointerIds(pointers), + oldTouchedWindow.getDownTimeInTarget(deviceId), + /*pointerDisplayId=*/std::nullopt, dump, targets); state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper); } @@ -7281,12 +7140,14 @@ void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFl } } -void InputDispatcher::transferWallpaperTouch( +std::pair<std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>, + std::list<InputDispatcher::DispatcherTouchState::PointerDownArgs>> +InputDispatcher::DispatcherTouchState::transferWallpaperTouch( + const sp<gui::WindowInfoHandle> fromWindowHandle, + const sp<gui::WindowInfoHandle> toWindowHandle, TouchState& state, + android::DeviceId deviceId, const std::vector<PointerProperties>& pointers, ftl::Flags<InputTarget::Flags> oldTargetFlags, - ftl::Flags<InputTarget::Flags> newTargetFlags, const sp<WindowInfoHandle> fromWindowHandle, - const sp<WindowInfoHandle> toWindowHandle, TouchState& state, DeviceId deviceId, - const std::vector<PointerProperties>& pointers, - const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) { + ftl::Flags<InputTarget::Flags> newTargetFlags) { const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) && fromWindowHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER); @@ -7297,16 +7158,16 @@ void InputDispatcher::transferWallpaperTouch( const sp<WindowInfoHandle> oldWallpaper = oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr; const sp<WindowInfoHandle> newWallpaper = - newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr; + newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(toWindowHandle) : nullptr; if (oldWallpaper == newWallpaper) { - return; + return {}; } + std::list<CancellationArgs> cancellations; + std::list<PointerDownArgs> pointerDowns; if (oldWallpaper != nullptr) { - CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, - "transferring touch focus to another window", traceTracker); state.removeWindowByToken(oldWallpaper->getToken()); - synthesizeCancelationEventsForWindowLocked(oldWallpaper, options); + cancellations.emplace_back(oldWallpaper, CancelationOptions::Mode::CANCEL_POINTER_EVENTS); } if (newWallpaper != nullptr) { @@ -7318,21 +7179,22 @@ void InputDispatcher::transferWallpaperTouch( state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags, deviceId, pointers, downTimeInTarget); std::shared_ptr<Connection> wallpaperConnection = - getConnectionLocked(newWallpaper->getToken()); + mConnectionManager.getConnection(newWallpaper->getToken()); if (wallpaperConnection != nullptr) { std::shared_ptr<Connection> toConnection = - getConnectionLocked(toWindowHandle->getToken()); + mConnectionManager.getConnection(toWindowHandle->getToken()); toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState); - synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection, - wallpaperFlags, traceTracker); + pointerDowns.emplace_back(downTimeInTarget, wallpaperConnection, wallpaperFlags); } + pointerDowns.emplace_back(downTimeInTarget, wallpaperConnection, wallpaperFlags); } + return {cancellations, pointerDowns}; } -sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow( +sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWallpaperWindowBelow( const sp<WindowInfoHandle>& windowHandle) const { const std::vector<sp<WindowInfoHandle>>& windowHandles = - mWindowInfos.getWindowHandlesForDisplay(windowHandle->getInfo()->displayId); + getWindowHandlesForDisplay(windowHandle->getInfo()->displayId); bool foundWindow = false; for (const sp<WindowInfoHandle>& otherHandle : windowHandles) { if (!foundWindow && otherHandle != windowHandle) { @@ -7364,18 +7226,7 @@ bool InputDispatcher::isPointerInWindow(const sp<android::IBinder>& token, ui::LogicalDisplayId displayId, DeviceId deviceId, int32_t pointerId) { std::scoped_lock _l(mLock); - auto touchStateIt = mTouchStatesByDisplay.find(displayId); - if (touchStateIt == mTouchStatesByDisplay.end()) { - return false; - } - for (const TouchedWindow& window : touchStateIt->second.windows) { - if (window.windowHandle->getToken() == token && - (window.hasTouchingPointer(deviceId, pointerId) || - window.hasHoveringPointer(deviceId, pointerId))) { - return true; - } - } - return false; + return mTouchStates.isPointerInWindow(token, displayId, deviceId, pointerId); } void InputDispatcher::setInputMethodConnectionIsActive(bool isActive) { @@ -7385,4 +7236,392 @@ void InputDispatcher::setInputMethodConnectionIsActive(bool isActive) { } } +void InputDispatcher::setDisplayTopology( + const android::DisplayTopologyGraph& displayTopologyGraph) { + std::scoped_lock _l(mLock); + mWindowInfos.setDisplayTopology(displayTopologyGraph); +} + +InputDispatcher::ConnectionManager::ConnectionManager(const sp<android::Looper>& looper) + : mLooper(looper) {} + +// This destructor is required to ensure cleanup of each input connection, so that the fd is +// removed from the looper. +InputDispatcher::ConnectionManager::~ConnectionManager() { + while (!mConnectionsByToken.empty()) { + std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second; + removeConnection(connection); + } +} + +void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection( + std::function<void(const std::shared_ptr<Connection>&)> f) const { + for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) { + for (const Monitor& monitor : monitors) { + f(monitor.connection); + } + } +} + +void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection( + ui::LogicalDisplayId displayId, + std::function<void(const std::shared_ptr<Connection>&)> f) const { + auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId); + if (monitorsIt == mGlobalMonitorsByDisplay.end()) return; + + for (const Monitor& monitor : monitorsIt->second) { + f(monitor.connection); + } +} + +void InputDispatcher::ConnectionManager::createGlobalInputMonitor( + ui::LogicalDisplayId displayId, std::unique_ptr<InputChannel>&& inputChannel, + const android::IdGenerator& idGenerator, gui::Pid pid, std::function<int(int)> callback) { + const int fd = inputChannel->getFd(); + std::shared_ptr<Connection> connection = + std::make_shared<Connection>(std::move(inputChannel), /*monitor=*/true, idGenerator); + sp<IBinder> token = connection->getToken(); + auto [_, inserted] = mConnectionsByToken.emplace(token, connection); + if (!inserted) { + ALOGE("Created a new connection, but the token %p is already known", token.get()); + } + mGlobalMonitorsByDisplay[displayId].emplace_back(connection, pid); + + mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback), nullptr); +} + +void InputDispatcher::ConnectionManager::createConnection( + std::unique_ptr<InputChannel>&& inputChannel, const android::IdGenerator& idGenerator, + std::function<int(int)> callback) { + const int fd = inputChannel->getFd(); + std::shared_ptr<Connection> connection = + std::make_shared<Connection>(std::move(inputChannel), /*monitor=*/false, idGenerator); + sp<IBinder> token = connection->getToken(); + auto [_, inserted] = mConnectionsByToken.try_emplace(token, connection); + if (!inserted) { + ALOGE("Created a new connection, but the token %p is already known", token.get()); + } + + mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback), nullptr); +} + +status_t InputDispatcher::ConnectionManager::removeConnection( + const std::shared_ptr<Connection>& connection) { + mConnectionsByToken.erase(connection->getToken()); + + if (connection->monitor) { + removeMonitorChannel(connection->getToken()); + } + + mLooper->removeFd(connection->inputPublisher.getChannel().getFd()); + + connection->status = Connection::Status::ZOMBIE; + return OK; +} + +std::string InputDispatcher::ConnectionManager::dump(nsecs_t currentTime) const { + std::string dump; + if (!mGlobalMonitorsByDisplay.empty()) { + for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) { + dump += StringPrintf("Global monitors on display %s:\n", displayId.toString().c_str()); + const size_t numMonitors = monitors.size(); + for (size_t i = 0; i < numMonitors; i++) { + const Monitor& monitor = monitors[i]; + const std::shared_ptr<Connection>& connection = monitor.connection; + dump += StringPrintf(INDENT "%zu: '%s', ", i, + connection->getInputChannelName().c_str()); + dump += "\n"; + } + } + } else { + dump += "Global Monitors: <none>\n"; + } + + if (!mConnectionsByToken.empty()) { + dump += "Connections:\n"; + for (const auto& [token, connection] : mConnectionsByToken) { + dump += StringPrintf(INDENT "%i: channelName='%s', " + "status=%s, monitor=%s, responsive=%s\n", + connection->inputPublisher.getChannel().getFd(), + connection->getInputChannelName().c_str(), + ftl::enum_string(connection->status).c_str(), + toString(connection->monitor), toString(connection->responsive)); + + if (!connection->outboundQueue.empty()) { + dump += StringPrintf(INDENT2 "OutboundQueue: length=%zu\n", + connection->outboundQueue.size()); + dump += dumpQueue(connection->outboundQueue, currentTime); + } + + if (!connection->waitQueue.empty()) { + dump += StringPrintf(INDENT2 "WaitQueue: length=%zu\n", + connection->waitQueue.size()); + dump += dumpQueue(connection->waitQueue, currentTime); + } + std::string inputStateDump = streamableToString(connection->inputState); + if (!inputStateDump.empty()) { + dump += INDENT2 "InputState: "; + dump += inputStateDump + "\n"; + } + } + } else { + dump += "Connections: <none>\n"; + } + return dump; +} + +void InputDispatcher::DispatcherWindowInfo::setMaximumObscuringOpacityForTouch(float opacity) { + if (opacity < 0 || opacity > 1) { + LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1"); + } + mMaximumObscuringOpacityForTouch = opacity; +} + +void InputDispatcher::DispatcherWindowInfo::setDisplayTopology( + const DisplayTopologyGraph& displayTopologyGraph) { + mTopology = displayTopologyGraph; +} + +InputDispatcher::DispatcherTouchState::DispatcherTouchState(const DispatcherWindowInfo& windowInfos, + const ConnectionManager& connections) + : mWindowInfos(windowInfos), mConnectionManager(connections) {} + +ftl::Flags<InputTarget::Flags> InputDispatcher::DispatcherTouchState::getTargetFlags( + const sp<WindowInfoHandle>& targetWindow, vec2 targetPosition, bool isSplit) { + ftl::Flags<InputTarget::Flags> targetFlags; + if (canReceiveForegroundTouches(*targetWindow->getInfo())) { + // There should only be one touched window that can be "foreground" for the pointer. + targetFlags |= InputTarget::Flags::FOREGROUND; + } + if (isSplit) { + targetFlags |= InputTarget::Flags::SPLIT; + } + if (mWindowInfos.isWindowObscuredAtPoint(targetWindow, targetPosition.x, targetPosition.y)) { + targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED; + } else if (mWindowInfos.isWindowObscured(targetWindow)) { + targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED; + } + return targetFlags; +} + +bool InputDispatcher::DispatcherTouchState::hasTouchingOrHoveringPointers( + ui::LogicalDisplayId displayId, int32_t deviceId) const { + bool hasTouchingOrHoveringPointers = false; + forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) { + hasTouchingOrHoveringPointers = + state.hasTouchingPointers(deviceId) || state.hasHoveringPointers(deviceId); + return hasTouchingOrHoveringPointers; + }); + return hasTouchingOrHoveringPointers; +} + +bool InputDispatcher::DispatcherTouchState::isPointerInWindow(const sp<android::IBinder>& token, + ui::LogicalDisplayId displayId, + android::DeviceId deviceId, + int32_t pointerId) const { + bool isPointerInWindow = false; + forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) { + for (const TouchedWindow& window : state.windows) { + if (window.windowHandle->getToken() == token && + (window.hasTouchingPointer(deviceId, pointerId) || + window.hasHoveringPointer(deviceId, pointerId))) { + isPointerInWindow = true; + return true; + } + } + return false; + }); + return isPointerInWindow; +} + +std::tuple<const sp<gui::WindowInfoHandle>&, ui::LogicalDisplayId> +InputDispatcher::DispatcherTouchState::findExistingTouchedWindowHandleAndDisplay( + const sp<android::IBinder>& token) const { + std::optional<std::tuple<const sp<gui::WindowInfoHandle>&, ui::LogicalDisplayId>> + touchedWindowHandleAndDisplay; + forAllTouchAndCursorStates([&](ui::LogicalDisplayId displayId, const TouchState& state) { + for (const TouchedWindow& w : state.windows) { + if (w.windowHandle->getToken() == token) { + touchedWindowHandleAndDisplay.emplace(std::ref(w.windowHandle), displayId); + return true; + } + } + return false; + }); + LOG_ALWAYS_FATAL_IF(!touchedWindowHandleAndDisplay.has_value(), + "%s : Touch state is out of sync: No touched window for token", __func__); + return touchedWindowHandleAndDisplay.value(); +} + +void InputDispatcher::DispatcherTouchState::forAllTouchedWindows( + std::function<void(const sp<gui::WindowInfoHandle>&)> f) const { + forAllTouchAndCursorStates([&](ui::LogicalDisplayId displayId, const TouchState& state) { + for (const TouchedWindow& window : state.windows) { + f(window.windowHandle); + } + return false; + }); +} + +void InputDispatcher::DispatcherTouchState::forAllTouchedWindowsOnDisplay( + ui::LogicalDisplayId displayId, + std::function<void(const sp<gui::WindowInfoHandle>&)> f) const { + forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) { + for (const TouchedWindow& window : state.windows) { + f(window.windowHandle); + } + return false; + }); +} + +std::string InputDispatcher::DispatcherTouchState::dump() const { + std::string dump; + if (mTouchStatesByDisplay.empty()) { + dump += "TouchStatesByDisplay: <no displays touched>\n"; + } else { + dump += "TouchStatesByDisplay:\n"; + for (const auto& [displayId, state] : mTouchStatesByDisplay) { + std::string touchStateDump = addLinePrefix(state.dump(), INDENT); + dump += INDENT + displayId.toString() + " : " + touchStateDump; + } + } + if (mCursorStateByDisplay.empty()) { + dump += "CursorStatesByDisplay: <no displays touched by cursor>\n"; + } else { + dump += "CursorStatesByDisplay:\n"; + for (const auto& [displayId, state] : mCursorStateByDisplay) { + std::string touchStateDump = addLinePrefix(state.dump(), INDENT); + dump += INDENT + displayId.toString() + " : " + touchStateDump; + } + } + return dump; +} + +void InputDispatcher::DispatcherTouchState::removeAllPointersForDevice(android::DeviceId deviceId) { + forAllTouchAndCursorStates([&](ui::LogicalDisplayId displayId, TouchState& state) { + state.removeAllPointersForDevice(deviceId); + return false; + }); +} + +void InputDispatcher::DispatcherTouchState::clear() { + mTouchStatesByDisplay.clear(); + mCursorStateByDisplay.clear(); +} + +void InputDispatcher::DispatcherTouchState::saveTouchStateForMotionEntry( + const android::inputdispatcher::MotionEntry& entry, + android::inputdispatcher::TouchState&& touchState) { + if (touchState.windows.empty()) { + eraseTouchStateForMotionEntry(entry); + return; + } + + if (InputFlags::connectedDisplaysCursorEnabled() && isMouseOrTouchpad(entry.source)) { + mCursorStateByDisplay[mWindowInfos.getPrimaryDisplayId(entry.displayId)] = + std::move(touchState); + } else { + mTouchStatesByDisplay[entry.displayId] = std::move(touchState); + } +} + +void InputDispatcher::DispatcherTouchState::eraseTouchStateForMotionEntry( + const android::inputdispatcher::MotionEntry& entry) { + if (InputFlags::connectedDisplaysCursorEnabled() && isMouseOrTouchpad(entry.source)) { + mCursorStateByDisplay.erase(mWindowInfos.getPrimaryDisplayId(entry.displayId)); + } else { + mTouchStatesByDisplay.erase(entry.displayId); + } +} + +const TouchState* InputDispatcher::DispatcherTouchState::getTouchStateForMotionEntry( + const android::inputdispatcher::MotionEntry& entry) const { + if (InputFlags::connectedDisplaysCursorEnabled() && isMouseOrTouchpad(entry.source)) { + auto touchStateIt = + mCursorStateByDisplay.find(mWindowInfos.getPrimaryDisplayId(entry.displayId)); + if (touchStateIt != mCursorStateByDisplay.end()) { + return &touchStateIt->second; + } + } else { + auto touchStateIt = mTouchStatesByDisplay.find(entry.displayId); + if (touchStateIt != mTouchStatesByDisplay.end()) { + return &touchStateIt->second; + } + } + return nullptr; +} + +void InputDispatcher::DispatcherTouchState::forTouchAndCursorStatesOnDisplay( + ui::LogicalDisplayId displayId, std::function<bool(const TouchState&)> f) const { + const auto touchStateIt = mTouchStatesByDisplay.find(displayId); + if (touchStateIt != mTouchStatesByDisplay.end() && f(touchStateIt->second)) { + return; + } + + // DisplayId for the Cursor state may not be same as supplied displayId if display is part of + // topology. Instead we should to check from the topology's primary display. + const auto cursorStateIt = + mCursorStateByDisplay.find(mWindowInfos.getPrimaryDisplayId(displayId)); + if (cursorStateIt != mCursorStateByDisplay.end()) { + f(cursorStateIt->second); + } +} + +void InputDispatcher::DispatcherTouchState::forTouchAndCursorStatesOnDisplay( + ui::LogicalDisplayId displayId, std::function<bool(TouchState&)> f) { + const_cast<const DispatcherTouchState&>(*this) + .forTouchAndCursorStatesOnDisplay(displayId, [&](const TouchState& state) { + return f(const_cast<TouchState&>(state)); + }); +} + +void InputDispatcher::DispatcherTouchState::forAllTouchAndCursorStates( + std::function<bool(ui::LogicalDisplayId, const TouchState&)> f) const { + for (auto& [displayId, state] : mTouchStatesByDisplay) { + if (f(displayId, state)) { + return; + } + } + for (auto& [displayId, state] : mCursorStateByDisplay) { + if (f(displayId, state)) { + return; + } + } +} + +void InputDispatcher::DispatcherTouchState::forAllTouchAndCursorStates( + std::function<bool(ui::LogicalDisplayId, TouchState&)> f) { + const_cast<const DispatcherTouchState&>(*this).forAllTouchAndCursorStates( + [&](ui::LogicalDisplayId displayId, const TouchState& constState) { + return f(displayId, const_cast<TouchState&>(constState)); + }); +} + +std::optional<std::tuple<TouchState&, TouchedWindow&, ui::LogicalDisplayId>> +InputDispatcher::DispatcherTouchState::findTouchStateWindowAndDisplay( + const sp<android::IBinder>& token) { + std::optional<std::tuple<TouchState&, TouchedWindow&, ui::LogicalDisplayId>> + touchStateWindowAndDisplay; + forAllTouchAndCursorStates([&](ui::LogicalDisplayId displayId, TouchState& state) { + for (TouchedWindow& w : state.windows) { + if (w.windowHandle->getToken() == token) { + touchStateWindowAndDisplay.emplace(std::ref(state), std::ref(w), displayId); + return true; + } + } + return false; + }); + return touchStateWindowAndDisplay; +} + +bool InputDispatcher::DispatcherTouchState::isStylusActiveInDisplay( + ui::LogicalDisplayId displayId) const { + const auto it = mTouchStatesByDisplay.find(displayId); + if (it == mTouchStatesByDisplay.end()) { + return false; + } + const TouchState& state = it->second; + return state.hasActiveStylus(); +} + } // namespace android::inputdispatcher diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index fd550dd396..38f782573a 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -164,6 +164,8 @@ public: void setInputMethodConnectionIsActive(bool isActive) override; + void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) override; + private: enum class DropReason { NOT_DROPPED, @@ -224,6 +226,316 @@ private: /** Stores the latest user-activity poke event times per user activity types. */ std::array<nsecs_t, USER_ACTIVITY_EVENT_LAST + 1> mLastUserActivityTimes GUARDED_BY(mLock); + template <typename T> + struct StrongPointerHash { + std::size_t operator()(const sp<T>& b) const { return std::hash<T*>{}(b.get()); } + }; + + class ConnectionManager { + public: + ConnectionManager(const sp<Looper>& lopper); + ~ConnectionManager(); + + std::shared_ptr<Connection> getConnection(const sp<IBinder>& inputConnectionToken) const; + + // Find a monitor pid by the provided token. + std::optional<gui::Pid> findMonitorPidByToken(const sp<IBinder>& token) const; + void forEachGlobalMonitorConnection( + std::function<void(const std::shared_ptr<Connection>&)> f) const; + void forEachGlobalMonitorConnection( + ui::LogicalDisplayId displayId, + std::function<void(const std::shared_ptr<Connection>&)> f) const; + + void createGlobalInputMonitor(ui::LogicalDisplayId displayId, + std::unique_ptr<InputChannel>&& inputChannel, + const IdGenerator& idGenerator, gui::Pid pid, + std::function<int(int)> callback); + + status_t removeConnection(const std::shared_ptr<Connection>& connection); + + void createConnection(std::unique_ptr<InputChannel>&& inputChannel, + const IdGenerator& idGenerator, std::function<int(int)> callback); + + std::string dump(nsecs_t currentTime) const; + + private: + const sp<Looper> mLooper; + + // All registered connections mapped by input channel token. + std::unordered_map<sp<IBinder>, std::shared_ptr<Connection>, StrongPointerHash<IBinder>> + mConnectionsByToken; + + // Input channels that will receive a copy of all input events sent to the provided display. + std::unordered_map<ui::LogicalDisplayId, std::vector<Monitor>> mGlobalMonitorsByDisplay; + + void removeMonitorChannel(const sp<IBinder>& connectionToken); + }; + + ConnectionManager mConnectionManager GUARDED_BY(mLock); + + class DispatcherWindowInfo { + public: + struct TouchOcclusionInfo { + bool hasBlockingOcclusion; + float obscuringOpacity; + std::string obscuringPackage; + gui::Uid obscuringUid = gui::Uid::INVALID; + std::vector<std::string> debugInfo; + }; + + void setWindowHandlesForDisplay( + ui::LogicalDisplayId displayId, + std::vector<sp<android::gui::WindowInfoHandle>>&& windowHandles); + + void setDisplayInfos(const std::vector<android::gui::DisplayInfo>& displayInfos); + + void removeDisplay(ui::LogicalDisplayId displayId); + + void setMaximumObscuringOpacityForTouch(float opacity); + + void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph); + + // Get a reference to window handles by display, return an empty vector if not found. + const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesForDisplay( + ui::LogicalDisplayId displayId) const; + + void forEachWindowHandle( + std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const; + + void forEachDisplayId(std::function<void(ui::LogicalDisplayId)> f) const; + + // Get the transform for display, returns Identity-transform if display is missing. + ui::Transform getDisplayTransform(ui::LogicalDisplayId displayId) const; + + // Get the raw transform to use for motion events going to the given window. Optionally a + // pointer displayId may be supplied if pointer is on a different display from the window. + ui::Transform getRawTransform( + const android::gui::WindowInfo& windowInfo, + std::optional<ui::LogicalDisplayId> pointerDisplayId = std::nullopt) const; + + // Lookup for WindowInfoHandle from token and optionally a display-id. In cases where + // display-id is not provided lookup is done for all displays. + sp<android::gui::WindowInfoHandle> findWindowHandle( + const sp<IBinder>& windowHandleToken, + std::optional<ui::LogicalDisplayId> displayId = {}) const; + + // Lookup for WindowInfoHandle from token and a display-id. Lookup is done for all connected + // displays in the topology of the queried display. + sp<android::gui::WindowInfoHandle> findWindowHandleOnConnectedDisplays( + const sp<IBinder>& windowHandleToken, ui::LogicalDisplayId displayId) const; + + bool isWindowPresent(const sp<android::gui::WindowInfoHandle>& windowHandle) const; + + // Returns the touched window at the given location, excluding the ignoreWindow if provided. + sp<android::gui::WindowInfoHandle> findTouchedWindowAt( + ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false, + const sp<android::gui::WindowInfoHandle> ignoreWindow = nullptr) const; + + TouchOcclusionInfo computeTouchOcclusionInfo( + const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const; + + bool isWindowObscured(const sp<android::gui::WindowInfoHandle>& windowHandle) const; + + bool isWindowObscuredAtPoint(const sp<android::gui::WindowInfoHandle>& windowHandle, + float x, float y) const; + + sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow( + const sp<android::gui::WindowInfoHandle>& windowHandle) const; + + bool isTouchTrusted(const TouchOcclusionInfo& occlusionInfo) const; + + // Returns topology's primary display if the display belongs to it, otherwise the + // same displayId. + ui::LogicalDisplayId getPrimaryDisplayId(ui::LogicalDisplayId displayId) const; + + bool areDisplaysConnected(ui::LogicalDisplayId display1, + ui::LogicalDisplayId display2) const; + + std::string dumpDisplayAndWindowInfo() const; + + private: + std::vector<ui::LogicalDisplayId> getConnectedDisplays( + ui::LogicalDisplayId displayId) const; + + sp<android::gui::WindowInfoHandle> findWindowHandleOnDisplay( + const sp<IBinder>& windowHandleToken, ui::LogicalDisplayId displayId) const; + + std::unordered_map<ui::LogicalDisplayId /*displayId*/, + std::vector<sp<android::gui::WindowInfoHandle>>> + mWindowHandlesByDisplay; + std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo> + mDisplayInfos; + float mMaximumObscuringOpacityForTouch{1.0f}; + + // Topology is initialized with default-constructed value, which is an empty topology until + // we receive setDisplayTopology call. Meanwhile we will treat every display as an + // independent display. + DisplayTopologyGraph mTopology; + }; + + DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock); + + class DispatcherTouchState { + public: + struct CancellationArgs { + const sp<gui::WindowInfoHandle> windowHandle; + CancelationOptions::Mode mode; + std::optional<DeviceId> deviceId{std::nullopt}; + ui::LogicalDisplayId displayId{ui::LogicalDisplayId::INVALID}; + std::bitset<MAX_POINTER_ID + 1> pointerIds{}; + }; + + struct PointerDownArgs { + const nsecs_t downTimeInTarget; + const std::shared_ptr<Connection> connection; + const ftl::Flags<InputTarget::Flags> targetFlags; + }; + + DispatcherTouchState(const DispatcherWindowInfo& windowInfos, + const ConnectionManager& connections); + + void addPointerWindowTarget(const sp<android::gui::WindowInfoHandle>& windowHandle, + InputTarget::DispatchMode dispatchMode, + ftl::Flags<InputTarget::Flags> targetFlags, + std::bitset<MAX_POINTER_ID + 1> pointerIds, + std::optional<nsecs_t> firstDownTimeInTarget, + std::optional<ui::LogicalDisplayId> pointerDisplayId, + std::function<void()> dump, + std::vector<InputTarget>& inputTargets); + + base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult> + findTouchedWindowTargets(nsecs_t currentTime, const MotionEntry& entry, + const sp<android::gui::WindowInfoHandle> dragWindow, + std::function<void(const MotionEntry&)> addDragEvent, + std::function<void()> dump); + + sp<android::gui::WindowInfoHandle> findTouchedForegroundWindow( + ui::LogicalDisplayId displayId) const; + + bool hasTouchingOrHoveringPointers(ui::LogicalDisplayId displayId, int32_t deviceId) const; + + bool isPointerInWindow(const sp<android::IBinder>& token, ui::LogicalDisplayId displayId, + DeviceId deviceId, int32_t pointerId) const; + + // Find an existing touched windowHandle and display by token. + std::tuple<const sp<gui::WindowInfoHandle>&, ui::LogicalDisplayId> + findExistingTouchedWindowHandleAndDisplay(const sp<IBinder>& token) const; + + void forAllTouchedWindows(std::function<void(const sp<gui::WindowInfoHandle>&)> f) const; + + void forAllTouchedWindowsOnDisplay( + ui::LogicalDisplayId displayId, + std::function<void(const sp<gui::WindowInfoHandle>&)> f) const; + + std::string dump() const; + + // Updates the touchState for display from WindowInfo, + // returns list of CancellationArgs for every cancelled touch + std::list<CancellationArgs> updateFromWindowInfo(ui::LogicalDisplayId displayId); + + void removeAllPointersForDevice(DeviceId deviceId); + + // transfer touch between provided tokens, returns destination WindowHandle, deviceId, + // pointers, list of cancelled windows and pointers on successful transfer. + std::optional< + std::tuple<sp<gui::WindowInfoHandle>, DeviceId, std::vector<PointerProperties>, + std::list<CancellationArgs>, std::list<PointerDownArgs>>> + transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken); + + base::Result<std::list<CancellationArgs>, status_t> pilferPointers( + const sp<IBinder>& token, const Connection& requestingConnection); + + void clear(); + + private: + std::unordered_map<ui::LogicalDisplayId, TouchState> mTouchStatesByDisplay; + + // As there can be only one CursorState per topology group, we will treat all displays in + // the topology as one connected display-group. These will be identified by + // DisplayTopologyGraph::primaryDisplayId. + // Cursor on the any of the displays that are not part of the topology will be identified by + // the displayId similar to mTouchStatesByDisplay. + std::unordered_map<ui::LogicalDisplayId, TouchState> mCursorStateByDisplay; + + // The supplied lambda is invoked for each touch and cursor state of the display. + // The function iterates until the lambda returns true, effectively performing a 'break' + // from the iteration. + void forTouchAndCursorStatesOnDisplay(ui::LogicalDisplayId displayId, + std::function<bool(const TouchState&)> f) const; + + void forTouchAndCursorStatesOnDisplay(ui::LogicalDisplayId displayId, + std::function<bool(TouchState&)> f); + + // The supplied lambda is invoked for each touchState. The function iterates until + // the lambda returns true, effectively performing a 'break' from the iteration. + void forAllTouchAndCursorStates( + std::function<bool(ui::LogicalDisplayId, const TouchState&)> f) const; + + void forAllTouchAndCursorStates(std::function<bool(ui::LogicalDisplayId, TouchState&)> f); + + std::optional<std::tuple<TouchState&, TouchedWindow&, ui::LogicalDisplayId>> + findTouchStateWindowAndDisplay(const sp<IBinder>& token); + + std::pair<std::list<CancellationArgs>, std::list<PointerDownArgs>> transferWallpaperTouch( + const sp<gui::WindowInfoHandle> fromWindowHandle, + const sp<gui::WindowInfoHandle> toWindowHandle, TouchState& state, + DeviceId deviceId, const std::vector<PointerProperties>& pointers, + ftl::Flags<InputTarget::Flags> oldTargetFlags, + ftl::Flags<InputTarget::Flags> newTargetFlags); + + void saveTouchStateForMotionEntry(const MotionEntry& entry, TouchState&& touchState); + + void eraseTouchStateForMotionEntry(const MotionEntry& entry); + + const TouchState* getTouchStateForMotionEntry( + const android::inputdispatcher::MotionEntry& entry) const; + + bool canWindowReceiveMotion(const sp<gui::WindowInfoHandle>& window, + const MotionEntry& motionEntry) const; + + // Return true if stylus is currently down anywhere on the specified display, + // and false otherwise. + bool isStylusActiveInDisplay(ui::LogicalDisplayId displayId) const; + + std::list<CancellationArgs> eraseRemovedWindowsFromWindowInfo( + TouchState& state, ui::LogicalDisplayId displayId); + + std::list<CancellationArgs> updateHoveringStateFromWindowInfo( + TouchState& state, ui::LogicalDisplayId displayId); + + std::vector<InputTarget> findOutsideTargets(ui::LogicalDisplayId displayId, + const sp<gui::WindowInfoHandle>& touchedWindow, + int32_t pointerId, std::function<void()> dump); + + /** + * Slip the wallpaper touch if necessary. + * + * @param targetFlags the target flags + * @param oldWindowHandle the old window that the touch slipped out of + * @param newWindowHandle the new window that the touch is slipping into + * @param state the current touch state. This will be updated if necessary to reflect the + * new windows that are receiving touch. + * @param deviceId the device id of the current motion being processed + * @param pointerProperties the pointer properties of the current motion being processed + * @param targets the current targets to add the walpaper ones to + * @param eventTime the new downTime for the wallpaper target + */ + void slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags, + const sp<android::gui::WindowInfoHandle>& oldWindowHandle, + const sp<android::gui::WindowInfoHandle>& newWindowHandle, + TouchState& state, const MotionEntry& entry, + std::vector<InputTarget>& targets, std::function<void()> dump); + + ftl::Flags<InputTarget::Flags> getTargetFlags( + const sp<android::gui::WindowInfoHandle>& targetWindow, vec2 targetPosition, + bool isSplit); + + const DispatcherWindowInfo& mWindowInfos; + const ConnectionManager& mConnectionManager; + }; + + DispatcherTouchState mTouchStates GUARDED_BY(mLock); + // With each iteration, InputDispatcher nominally processes one queued event, // a timeout, or a response from an input consumer. // This method should only be called on the input dispatcher's own thread. @@ -252,39 +564,8 @@ private: // to transfer focus to a new application. std::shared_ptr<const EventEntry> mNextUnblockedEvent GUARDED_BY(mLock); - std::vector<InputTarget> findOutsideTargetsLocked( - ui::LogicalDisplayId displayId, const sp<android::gui::WindowInfoHandle>& touchedWindow, - int32_t pointerId) const REQUIRES(mLock); - - static sp<android::gui::WindowInfoHandle> findTouchedForegroundWindow( - const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay, - ui::LogicalDisplayId displayId); - - std::shared_ptr<Connection> getConnectionLocked(const sp<IBinder>& inputConnectionToken) const - REQUIRES(mLock); - - std::string getConnectionNameLocked(const sp<IBinder>& connectionToken) const REQUIRES(mLock); - - void removeConnectionLocked(const std::shared_ptr<Connection>& connection) REQUIRES(mLock); - status_t pilferPointersLocked(const sp<IBinder>& token) REQUIRES(mLock); - template <typename T> - struct StrongPointerHash { - std::size_t operator()(const sp<T>& b) const { return std::hash<T*>{}(b.get()); } - }; - - // All registered connections mapped by input channel token. - std::unordered_map<sp<IBinder>, std::shared_ptr<Connection>, StrongPointerHash<IBinder>> - mConnectionsByToken GUARDED_BY(mLock); - - // Find a monitor pid by the provided token. - std::optional<gui::Pid> findMonitorPidByTokenLocked(const sp<IBinder>& token) REQUIRES(mLock); - - // Input channels that will receive a copy of all input events sent to the provided display. - std::unordered_map<ui::LogicalDisplayId, std::vector<Monitor>> mGlobalMonitorsByDisplay - GUARDED_BY(mLock); - const HmacKeyManager mHmacKeyManager; const std::array<uint8_t, 32> getSignature(const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const; @@ -344,7 +625,6 @@ private: bool mDispatchEnabled GUARDED_BY(mLock); bool mDispatchFrozen GUARDED_BY(mLock); bool mInputFilterEnabled GUARDED_BY(mLock); - float mMaximumObscuringOpacityForTouch GUARDED_BY(mLock); // This map is not really needed, but it helps a lot with debugging (dumpsys input). // In the java layer, touch mode states are spread across multiple DisplayContent objects, @@ -362,66 +642,12 @@ private: }; sp<gui::WindowInfosListener> mWindowInfoListener; - class DispatcherWindowInfo { - public: - void setWindowHandlesForDisplay( - ui::LogicalDisplayId displayId, - std::vector<sp<android::gui::WindowInfoHandle>>&& windowHandles); - - void setDisplayInfos(const std::vector<android::gui::DisplayInfo>& displayInfos); - - void removeDisplay(ui::LogicalDisplayId displayId); - - // Get a reference to window handles by display, return an empty vector if not found. - const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesForDisplay( - ui::LogicalDisplayId displayId) const; - - void forEachWindowHandle( - std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const; - - void forEachDisplayId(std::function<void(ui::LogicalDisplayId)> f) const; - - // Get the transform for display, returns Identity-transform if display is missing. - ui::Transform getDisplayTransform(ui::LogicalDisplayId displayId) const; - - // Lookup for WindowInfoHandle from token and optionally a display-id. In cases where - // display-id is not provided lookup is done for all displays. - sp<android::gui::WindowInfoHandle> findWindowHandle( - const sp<IBinder>& windowHandleToken, - std::optional<ui::LogicalDisplayId> displayId = {}) const; - - bool isWindowPresent(const sp<android::gui::WindowInfoHandle>& windowHandle) const; - - // Returns the touched window at the given location, excluding the ignoreWindow if provided. - sp<android::gui::WindowInfoHandle> findTouchedWindowAt( - ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false, - const sp<android::gui::WindowInfoHandle> ignoreWindow = nullptr) const; - - std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt( - ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId, - const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) - const; - - std::string dumpDisplayAndWindowInfo() const; - - private: - std::unordered_map<ui::LogicalDisplayId /*displayId*/, - std::vector<sp<android::gui::WindowInfoHandle>>> - mWindowHandlesByDisplay; - std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo> - mDisplayInfos; - }; - - DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock); - void setInputWindowsLocked( const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles, ui::LogicalDisplayId displayId) REQUIRES(mLock); sp<android::gui::WindowInfoHandle> getFocusedWindowHandleLocked( ui::LogicalDisplayId displayId) const REQUIRES(mLock); - bool canWindowReceiveMotionLocked(const sp<android::gui::WindowInfoHandle>& window, - const MotionEntry& motionEntry) const REQUIRES(mLock); // Returns all the input targets (with their respective input channels) from the window handles // passed as argument. @@ -436,8 +662,6 @@ private: const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles, ui::LogicalDisplayId displayId) REQUIRES(mLock); - std::unordered_map<ui::LogicalDisplayId /*displayId*/, TouchState> mTouchStatesByDisplay - GUARDED_BY(mLock); std::unique_ptr<DragState> mDragState GUARDED_BY(mLock); void setFocusedApplicationLocked( @@ -577,22 +801,12 @@ private: base::Result<sp<android::gui::WindowInfoHandle>, android::os::InputEventInjectionResult> findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry, nsecs_t& nextWakeupTime) REQUIRES(mLock); - base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult> - findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) REQUIRES(mLock); - std::vector<Monitor> selectResponsiveMonitorsLocked( - const std::vector<Monitor>& gestureMonitors) const REQUIRES(mLock); void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle, InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags, std::optional<nsecs_t> firstDownTimeInTarget, std::vector<InputTarget>& inputTargets) const REQUIRES(mLock); - void addPointerWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle, - InputTarget::DispatchMode dispatchMode, - ftl::Flags<InputTarget::Flags> targetFlags, - std::bitset<MAX_POINTER_ID + 1> pointerIds, - std::optional<nsecs_t> firstDownTimeInTarget, - std::vector<InputTarget>& inputTargets) const REQUIRES(mLock); void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, ui::LogicalDisplayId displayId) REQUIRES(mLock); void pokeUserActivityLocked(const EventEntry& eventEntry) REQUIRES(mLock); @@ -601,30 +815,16 @@ private: void addDragEventLocked(const MotionEntry& entry) REQUIRES(mLock); void finishDragAndDrop(ui::LogicalDisplayId displayId, float x, float y) REQUIRES(mLock); - struct TouchOcclusionInfo { - bool hasBlockingOcclusion; - float obscuringOpacity; - std::string obscuringPackage; - gui::Uid obscuringUid = gui::Uid::INVALID; - std::vector<std::string> debugInfo; - }; - - TouchOcclusionInfo computeTouchOcclusionInfoLocked( - const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const - REQUIRES(mLock); - bool isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const REQUIRES(mLock); - bool isWindowObscuredAtPointLocked(const sp<android::gui::WindowInfoHandle>& windowHandle, - float x, float y) const REQUIRES(mLock); - bool isWindowObscuredLocked(const sp<android::gui::WindowInfoHandle>& windowHandle) const - REQUIRES(mLock); - std::string dumpWindowForTouchOcclusion(const android::gui::WindowInfo* info, - bool isTouchWindow) const; std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle, const sp<android::gui::WindowInfoHandle>& windowHandle); - bool shouldDropInput(const EventEntry& entry, - const sp<android::gui::WindowInfoHandle>& windowHandle) const - REQUIRES(mLock); + static std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt( + ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId, + const DispatcherWindowInfo& windowInfos); + + static bool shouldDropInput(const EventEntry& entry, + const sp<android::gui::WindowInfoHandle>& windowHandle, + const DispatcherWindowInfo& windowInfo); // Manage the dispatch cycle for a single connection. // These methods are deliberately not Interruptible because doing all of the work @@ -646,8 +846,7 @@ private: void finishDispatchCycleLocked(nsecs_t currentTime, const std::shared_ptr<Connection>& connection, uint32_t seq, bool handled, nsecs_t consumeTime) REQUIRES(mLock); - void abortBrokenDispatchCycleLocked(nsecs_t currentTime, - const std::shared_ptr<Connection>& connection, bool notify) + void abortBrokenDispatchCycleLocked(const std::shared_ptr<Connection>& connection, bool notify) REQUIRES(mLock); void drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue); void releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry); @@ -687,13 +886,10 @@ private: // Dump state. void dumpDispatchStateLocked(std::string& dump) const REQUIRES(mLock); - void dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const; void logDispatchStateLocked() const REQUIRES(mLock); std::string dumpPointerCaptureStateLocked() const REQUIRES(mLock); - // Registration. - void removeMonitorChannelLocked(const sp<IBinder>& connectionToken) REQUIRES(mLock); - status_t removeInputChannelLocked(const sp<IBinder>& connectionToken, bool notify) + status_t removeInputChannelLocked(const std::shared_ptr<Connection>& connection, bool notify) REQUIRES(mLock); // Interesting events that we might like to log or tell the framework about. @@ -723,21 +919,6 @@ private: const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry, bool handled) REQUIRES(mLock); - // Find touched state and touched window by token. - static std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId> - findTouchStateWindowAndDisplay( - const sp<IBinder>& token, - std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay); - - static std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId> - findTouchStateWindowAndDisplay( - const sp<IBinder>& token, - const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay); - - static bool windowHasTouchingPointers( - const sp<android::gui::WindowInfoHandle>& windowHandle, DeviceId deviceId, - const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay); - // Statistics gathering. nsecs_t mLastStatisticPushTime = 0; std::unique_ptr<InputEventTimelineProcessor> mInputEventTimelineProcessor GUARDED_BY(mLock); @@ -752,36 +933,6 @@ private: sp<InputReporterInterface> mReporter; - /** - * Slip the wallpaper touch if necessary. - * - * @param targetFlags the target flags - * @param oldWindowHandle the old window that the touch slipped out of - * @param newWindowHandle the new window that the touch is slipping into - * @param state the current touch state. This will be updated if necessary to reflect the new - * windows that are receiving touch. - * @param deviceId the device id of the current motion being processed - * @param pointerProperties the pointer properties of the current motion being processed - * @param targets the current targets to add the walpaper ones to - * @param eventTime the new downTime for the wallpaper target - */ - void slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags, - const sp<android::gui::WindowInfoHandle>& oldWindowHandle, - const sp<android::gui::WindowInfoHandle>& newWindowHandle, - TouchState& state, const MotionEntry& entry, - std::vector<InputTarget>& targets) const REQUIRES(mLock); - void transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags, - ftl::Flags<InputTarget::Flags> newTargetFlags, - const sp<android::gui::WindowInfoHandle> fromWindowHandle, - const sp<android::gui::WindowInfoHandle> toWindowHandle, - TouchState& state, DeviceId deviceId, - const std::vector<PointerProperties>& pointers, - const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) - REQUIRES(mLock); - - sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow( - const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock); - /** Stores the value of the input flag for per device input latency metrics. */ const bool mPerDeviceInputLatencyMetricsFlag = com::android::input::flags::enable_per_device_input_latency_metrics(); diff --git a/services/inputflinger/dispatcher/InputState.cpp b/services/inputflinger/dispatcher/InputState.cpp index 9b5a79b24d..782a54f09e 100644 --- a/services/inputflinger/dispatcher/InputState.cpp +++ b/services/inputflinger/dispatcher/InputState.cpp @@ -15,7 +15,9 @@ */ #include "DebugConfig.h" +#include "input/Input.h" #include "input/InputDevice.h" +#include "input/InputFlags.h" #include "InputState.h" @@ -221,10 +223,15 @@ ssize_t InputState::findKeyMemento(const KeyEntry& entry) const { } ssize_t InputState::findMotionMemento(const MotionEntry& entry, bool hovering) const { + // If we have connected displays a mouse can move between displays and displayId may change + // while a gesture is in-progress. + const bool skipDisplayCheck = + InputFlags::connectedDisplaysCursorEnabled() && isMouseOrTouchpad(entry.source); for (size_t i = 0; i < mMotionMementos.size(); i++) { const MotionMemento& memento = mMotionMementos[i]; if (memento.deviceId == entry.deviceId && memento.source == entry.source && - memento.displayId == entry.displayId && memento.hovering == hovering) { + memento.hovering == hovering && + (skipDisplayCheck || memento.displayId == entry.displayId)) { return i; } } @@ -338,7 +345,10 @@ bool InputState::shouldCancelPreviousStream(const MotionEntry& motionEntry) cons // would receive different events from each display. Since the TouchStates are per-display, // it's unlikely that those two streams would be consistent with each other. Therefore, // cancel the previous gesture if the display id changes. - if (motionEntry.displayId != lastMemento.displayId) { + // Except when we have connected-displays where a mouse may move across display boundaries. + const bool skipDisplayCheck = (InputFlags::connectedDisplaysCursorEnabled() && + isMouseOrTouchpad(motionEntry.source)); + if (!skipDisplayCheck && motionEntry.displayId != lastMemento.displayId) { LOG(INFO) << "Canceling stream: last displayId was " << lastMemento.displayId << " and new event is " << motionEntry; return true; diff --git a/services/inputflinger/dispatcher/InputTarget.h b/services/inputflinger/dispatcher/InputTarget.h index 90374f1481..76f3fe0d0c 100644 --- a/services/inputflinger/dispatcher/InputTarget.h +++ b/services/inputflinger/dispatcher/InputTarget.h @@ -77,8 +77,8 @@ public: // (ignored for KeyEvents) float globalScaleFactor = 1.0f; - // Current display transform. Used for compatibility for raw coordinates. - ui::Transform displayTransform; + // The raw coordinate transform that's used for compatibility for MotionEvent's getRaw APIs. + ui::Transform rawTransform; // Event time for the first motion event (ACTION_DOWN) dispatched to this input target if // FLAG_SPLIT is set. diff --git a/services/inputflinger/dispatcher/LatencyAggregatorWithHistograms.cpp b/services/inputflinger/dispatcher/LatencyAggregatorWithHistograms.cpp index 881a96b28e..4da05c19cf 100644 --- a/services/inputflinger/dispatcher/LatencyAggregatorWithHistograms.cpp +++ b/services/inputflinger/dispatcher/LatencyAggregatorWithHistograms.cpp @@ -133,10 +133,11 @@ void LatencyAggregatorWithHistograms::addSampleToHistogram( } void LatencyAggregatorWithHistograms::processStatistics(const InputEventTimeline& timeline) { - // Only gather data for Down, Move and Up motion events and Key events + // Only gather data for Down, Move, Up and Scroll motion events and Key events if (!(timeline.inputEventActionType == InputEventActionType::MOTION_ACTION_DOWN || timeline.inputEventActionType == InputEventActionType::MOTION_ACTION_MOVE || timeline.inputEventActionType == InputEventActionType::MOTION_ACTION_UP || + timeline.inputEventActionType == InputEventActionType::MOTION_ACTION_SCROLL || timeline.inputEventActionType == InputEventActionType::KEY)) return; diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h index 463a95238b..ab039c34ef 100644 --- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h +++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h @@ -24,6 +24,7 @@ #include <android/os/InputEventInjectionSync.h> #include <gui/InputApplication.h> #include <gui/WindowInfo.h> +#include <input/DisplayTopologyGraph.h> #include <input/InputDevice.h> #include <input/InputTransport.h> #include <unordered_map> @@ -243,6 +244,11 @@ public: * Notify the dispatcher that the state of the input method connection changed. */ virtual void setInputMethodConnectionIsActive(bool isActive) = 0; + + /* + * Notify the dispatcher of the latest DisplayTopology. + */ + virtual void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) = 0; }; } // namespace android diff --git a/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.cpp b/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.cpp deleted file mode 100644 index 0b17507c2c..0000000000 --- a/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AndroidInputEventProtoConverter.h" - -#include <android-base/logging.h> -#include <perfetto/trace/android/android_input_event.pbzero.h> - -namespace android::inputdispatcher::trace { - -namespace { - -using namespace ftl::flag_operators; - -// The trace config to use for maximal tracing. -const impl::TraceConfig CONFIG_TRACE_ALL{ - .flags = impl::TraceFlag::TRACE_DISPATCHER_INPUT_EVENTS | - impl::TraceFlag::TRACE_DISPATCHER_WINDOW_DISPATCH, - .rules = {impl::TraceRule{.level = impl::TraceLevel::TRACE_LEVEL_COMPLETE, - .matchAllPackages = {}, - .matchAnyPackages = {}, - .matchSecure{}, - .matchImeConnectionActive = {}}}, -}; - -} // namespace - -void AndroidInputEventProtoConverter::toProtoMotionEvent(const TracedMotionEvent& event, - proto::AndroidMotionEvent& outProto, - bool isRedacted) { - outProto.set_event_id(event.id); - outProto.set_event_time_nanos(event.eventTime); - outProto.set_down_time_nanos(event.downTime); - outProto.set_source(event.source); - outProto.set_action(event.action); - outProto.set_device_id(event.deviceId); - outProto.set_display_id(event.displayId.val()); - outProto.set_classification(static_cast<int32_t>(event.classification)); - outProto.set_flags(event.flags); - outProto.set_policy_flags(event.policyFlags); - - if (!isRedacted) { - outProto.set_cursor_position_x(event.xCursorPosition); - outProto.set_cursor_position_y(event.yCursorPosition); - outProto.set_meta_state(event.metaState); - } - - for (uint32_t i = 0; i < event.pointerProperties.size(); i++) { - auto* pointer = outProto.add_pointer(); - - const auto& props = event.pointerProperties[i]; - pointer->set_pointer_id(props.id); - pointer->set_tool_type(static_cast<int32_t>(props.toolType)); - - const auto& coords = event.pointerCoords[i]; - auto bits = BitSet64(coords.bits); - for (int32_t axisIndex = 0; !bits.isEmpty(); axisIndex++) { - const auto axis = bits.clearFirstMarkedBit(); - auto axisEntry = pointer->add_axis_value(); - axisEntry->set_axis(axis); - - if (!isRedacted) { - axisEntry->set_value(coords.values[axisIndex]); - } - } - } -} - -void AndroidInputEventProtoConverter::toProtoKeyEvent(const TracedKeyEvent& event, - proto::AndroidKeyEvent& outProto, - bool isRedacted) { - outProto.set_event_id(event.id); - outProto.set_event_time_nanos(event.eventTime); - outProto.set_down_time_nanos(event.downTime); - outProto.set_source(event.source); - outProto.set_action(event.action); - outProto.set_device_id(event.deviceId); - outProto.set_display_id(event.displayId.val()); - outProto.set_repeat_count(event.repeatCount); - outProto.set_flags(event.flags); - outProto.set_policy_flags(event.policyFlags); - - if (!isRedacted) { - outProto.set_key_code(event.keyCode); - outProto.set_scan_code(event.scanCode); - outProto.set_meta_state(event.metaState); - } -} - -void AndroidInputEventProtoConverter::toProtoWindowDispatchEvent( - const WindowDispatchArgs& args, proto::AndroidWindowInputDispatchEvent& outProto, - bool isRedacted) { - std::visit([&](auto entry) { outProto.set_event_id(entry.id); }, args.eventEntry); - outProto.set_vsync_id(args.vsyncId); - outProto.set_window_id(args.windowId); - outProto.set_resolved_flags(args.resolvedFlags); - - if (isRedacted) { - return; - } - if (auto* motion = std::get_if<TracedMotionEvent>(&args.eventEntry); motion != nullptr) { - for (size_t i = 0; i < motion->pointerProperties.size(); i++) { - auto* pointerProto = outProto.add_dispatched_pointer(); - pointerProto->set_pointer_id(motion->pointerProperties[i].id); - const auto rawXY = - MotionEvent::calculateTransformedXY(motion->source, args.rawTransform, - motion->pointerCoords[i].getXYValue()); - pointerProto->set_x_in_display(rawXY.x); - pointerProto->set_y_in_display(rawXY.y); - - const auto& coords = motion->pointerCoords[i]; - const auto coordsInWindow = - MotionEvent::calculateTransformedCoords(motion->source, motion->flags, - args.transform, coords); - auto bits = BitSet64(coords.bits); - for (int32_t axisIndex = 0; !bits.isEmpty(); axisIndex++) { - const uint32_t axis = bits.clearFirstMarkedBit(); - const float axisValueInWindow = coordsInWindow.values[axisIndex]; - if (coords.values[axisIndex] != axisValueInWindow) { - auto* axisEntry = pointerProto->add_axis_value_in_window(); - axisEntry->set_axis(axis); - axisEntry->set_value(axisValueInWindow); - } - } - } - } -} - -impl::TraceConfig AndroidInputEventProtoConverter::parseConfig( - proto::AndroidInputEventConfig::Decoder& protoConfig) { - if (protoConfig.has_mode() && - protoConfig.mode() == proto::AndroidInputEventConfig::TRACE_MODE_TRACE_ALL) { - // User has requested the preset for maximal tracing - return CONFIG_TRACE_ALL; - } - - impl::TraceConfig config; - - // Parse trace flags - if (protoConfig.has_trace_dispatcher_input_events() && - protoConfig.trace_dispatcher_input_events()) { - config.flags |= impl::TraceFlag::TRACE_DISPATCHER_INPUT_EVENTS; - } - if (protoConfig.has_trace_dispatcher_window_dispatch() && - protoConfig.trace_dispatcher_window_dispatch()) { - config.flags |= impl::TraceFlag::TRACE_DISPATCHER_WINDOW_DISPATCH; - } - - // Parse trace rules - auto rulesIt = protoConfig.rules(); - while (rulesIt) { - proto::AndroidInputEventConfig::TraceRule::Decoder protoRule{rulesIt->as_bytes()}; - config.rules.emplace_back(); - auto& rule = config.rules.back(); - - rule.level = protoRule.has_trace_level() - ? static_cast<impl::TraceLevel>(protoRule.trace_level()) - : impl::TraceLevel::TRACE_LEVEL_NONE; - - if (protoRule.has_match_all_packages()) { - auto pkgIt = protoRule.match_all_packages(); - while (pkgIt) { - rule.matchAllPackages.emplace_back(pkgIt->as_std_string()); - pkgIt++; - } - } - - if (protoRule.has_match_any_packages()) { - auto pkgIt = protoRule.match_any_packages(); - while (pkgIt) { - rule.matchAnyPackages.emplace_back(pkgIt->as_std_string()); - pkgIt++; - } - } - - if (protoRule.has_match_secure()) { - rule.matchSecure = protoRule.match_secure(); - } - - if (protoRule.has_match_ime_connection_active()) { - rule.matchImeConnectionActive = protoRule.match_ime_connection_active(); - } - - rulesIt++; - } - - return config; -} - -} // namespace android::inputdispatcher::trace diff --git a/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.h b/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.h index 887913f463..c19d278370 100644 --- a/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.h +++ b/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.h @@ -26,20 +26,214 @@ namespace proto = perfetto::protos::pbzero; namespace android::inputdispatcher::trace { +namespace internal { + +using namespace ftl::flag_operators; + +// The trace config to use for maximal tracing. +const impl::TraceConfig CONFIG_TRACE_ALL{ + .flags = impl::TraceFlag::TRACE_DISPATCHER_INPUT_EVENTS | + impl::TraceFlag::TRACE_DISPATCHER_WINDOW_DISPATCH, + .rules = {impl::TraceRule{.level = impl::TraceLevel::TRACE_LEVEL_COMPLETE, + .matchAllPackages = {}, + .matchAnyPackages = {}, + .matchSecure{}, + .matchImeConnectionActive = {}}}, +}; + +template <typename Pointer> +void writeAxisValue(Pointer* pointer, int32_t axis, float value, bool isRedacted) { + auto* axisEntry = pointer->add_axis_value(); + axisEntry->set_axis(axis); + + if (!isRedacted) { + axisEntry->set_value(value); + } +} + +} // namespace internal + /** * Write traced events into Perfetto protos. + * + * This class is templated so that the logic can be tested while substituting the proto classes + * auto-generated by Perfetto's pbzero library with mock implementations. */ +template <typename ProtoMotion, typename ProtoKey, typename ProtoDispatch, + typename ProtoConfigDecoder> class AndroidInputEventProtoConverter { public: - static void toProtoMotionEvent(const TracedMotionEvent& event, - proto::AndroidMotionEvent& outProto, bool isRedacted); - static void toProtoKeyEvent(const TracedKeyEvent& event, proto::AndroidKeyEvent& outProto, - bool isRedacted); - static void toProtoWindowDispatchEvent(const WindowDispatchArgs&, - proto::AndroidWindowInputDispatchEvent& outProto, - bool isRedacted); - - static impl::TraceConfig parseConfig(proto::AndroidInputEventConfig::Decoder& protoConfig); + static void toProtoMotionEvent(const TracedMotionEvent& event, ProtoMotion& outProto, + bool isRedacted) { + outProto.set_event_id(event.id); + outProto.set_event_time_nanos(event.eventTime); + outProto.set_down_time_nanos(event.downTime); + outProto.set_source(event.source); + outProto.set_action(event.action); + outProto.set_device_id(event.deviceId); + outProto.set_display_id(event.displayId.val()); + outProto.set_classification(static_cast<int32_t>(event.classification)); + outProto.set_flags(event.flags); + outProto.set_policy_flags(event.policyFlags); + outProto.set_button_state(event.buttonState); + outProto.set_action_button(event.actionButton); + + if (!isRedacted) { + outProto.set_cursor_position_x(event.xCursorPosition); + outProto.set_cursor_position_y(event.yCursorPosition); + outProto.set_meta_state(event.metaState); + outProto.set_precision_x(event.xPrecision); + outProto.set_precision_y(event.yPrecision); + } + + for (uint32_t i = 0; i < event.pointerProperties.size(); i++) { + auto* pointer = outProto.add_pointer(); + + const auto& props = event.pointerProperties[i]; + pointer->set_pointer_id(props.id); + pointer->set_tool_type(static_cast<int32_t>(props.toolType)); + + const auto& coords = event.pointerCoords[i]; + auto bits = BitSet64(coords.bits); + + if (isFromSource(event.source, AINPUT_SOURCE_CLASS_POINTER)) { + // Always include the X and Y axes for pointer events, since the + // bits will not be marked if the value is 0. + for (const auto axis : {AMOTION_EVENT_AXIS_X, AMOTION_EVENT_AXIS_Y}) { + if (!bits.hasBit(axis)) { + internal::writeAxisValue(pointer, axis, 0.0f, isRedacted); + } + } + } + + for (int32_t axisIndex = 0; !bits.isEmpty(); axisIndex++) { + const auto axis = bits.clearFirstMarkedBit(); + internal::writeAxisValue(pointer, axis, coords.values[axisIndex], isRedacted); + } + } + } + + static void toProtoKeyEvent(const TracedKeyEvent& event, ProtoKey& outProto, bool isRedacted) { + outProto.set_event_id(event.id); + outProto.set_event_time_nanos(event.eventTime); + outProto.set_down_time_nanos(event.downTime); + outProto.set_source(event.source); + outProto.set_action(event.action); + outProto.set_device_id(event.deviceId); + outProto.set_display_id(event.displayId.val()); + outProto.set_repeat_count(event.repeatCount); + outProto.set_flags(event.flags); + outProto.set_policy_flags(event.policyFlags); + + if (!isRedacted) { + outProto.set_key_code(event.keyCode); + outProto.set_scan_code(event.scanCode); + outProto.set_meta_state(event.metaState); + } + } + + static void toProtoWindowDispatchEvent(const WindowDispatchArgs& args, ProtoDispatch& outProto, + bool isRedacted) { + std::visit([&](auto entry) { outProto.set_event_id(entry.id); }, args.eventEntry); + outProto.set_vsync_id(args.vsyncId); + outProto.set_window_id(args.windowId); + outProto.set_resolved_flags(args.resolvedFlags); + + if (isRedacted) { + return; + } + if (auto* motion = std::get_if<TracedMotionEvent>(&args.eventEntry); motion != nullptr) { + for (size_t i = 0; i < motion->pointerProperties.size(); i++) { + auto* pointerProto = outProto.add_dispatched_pointer(); + pointerProto->set_pointer_id(motion->pointerProperties[i].id); + const auto& coords = motion->pointerCoords[i]; + const auto rawXY = + MotionEvent::calculateTransformedXY(motion->source, args.rawTransform, + coords.getXYValue()); + if (coords.getXYValue() != rawXY) { + // These values are only traced if they were modified by the raw transform + // to save space. Trace consumers should be aware of this optimization. + pointerProto->set_x_in_display(rawXY.x); + pointerProto->set_y_in_display(rawXY.y); + } + + const auto coordsInWindow = + MotionEvent::calculateTransformedCoords(motion->source, motion->flags, + args.transform, coords); + auto bits = BitSet64(coords.bits); + for (int32_t axisIndex = 0; !bits.isEmpty(); axisIndex++) { + const uint32_t axis = bits.clearFirstMarkedBit(); + const float axisValueInWindow = coordsInWindow.values[axisIndex]; + // Only values that are modified by the window transform are traced. + if (coords.values[axisIndex] != axisValueInWindow) { + auto* axisEntry = pointerProto->add_axis_value_in_window(); + axisEntry->set_axis(axis); + axisEntry->set_value(axisValueInWindow); + } + } + } + } + } + + static impl::TraceConfig parseConfig(ProtoConfigDecoder& protoConfig) { + if (protoConfig.has_mode() && + protoConfig.mode() == proto::AndroidInputEventConfig::TRACE_MODE_TRACE_ALL) { + // User has requested the preset for maximal tracing + return internal::CONFIG_TRACE_ALL; + } + + impl::TraceConfig config; + + // Parse trace flags + if (protoConfig.has_trace_dispatcher_input_events() && + protoConfig.trace_dispatcher_input_events()) { + config.flags |= impl::TraceFlag::TRACE_DISPATCHER_INPUT_EVENTS; + } + if (protoConfig.has_trace_dispatcher_window_dispatch() && + protoConfig.trace_dispatcher_window_dispatch()) { + config.flags |= impl::TraceFlag::TRACE_DISPATCHER_WINDOW_DISPATCH; + } + + // Parse trace rules + auto rulesIt = protoConfig.rules(); + while (rulesIt) { + proto::AndroidInputEventConfig::TraceRule::Decoder protoRule{rulesIt->as_bytes()}; + config.rules.emplace_back(); + auto& rule = config.rules.back(); + + rule.level = protoRule.has_trace_level() + ? static_cast<impl::TraceLevel>(protoRule.trace_level()) + : impl::TraceLevel::TRACE_LEVEL_NONE; + + if (protoRule.has_match_all_packages()) { + auto pkgIt = protoRule.match_all_packages(); + while (pkgIt) { + rule.matchAllPackages.emplace_back(pkgIt->as_std_string()); + pkgIt++; + } + } + + if (protoRule.has_match_any_packages()) { + auto pkgIt = protoRule.match_any_packages(); + while (pkgIt) { + rule.matchAnyPackages.emplace_back(pkgIt->as_std_string()); + pkgIt++; + } + } + + if (protoRule.has_match_secure()) { + rule.matchSecure = protoRule.match_secure(); + } + + if (protoRule.has_match_ime_connection_active()) { + rule.matchImeConnectionActive = protoRule.match_ime_connection_active(); + } + + rulesIt++; + } + + return config; + } }; } // namespace android::inputdispatcher::trace diff --git a/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h b/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h index 761d619cec..2ff6e1c84d 100644 --- a/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h +++ b/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h @@ -50,7 +50,7 @@ struct TracedKeyEvent { uint32_t policyFlags; int32_t deviceId; uint32_t source; - ui::LogicalDisplayId displayId; + ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID; int32_t action; int32_t keyCode; int32_t scanCode; @@ -70,7 +70,7 @@ struct TracedMotionEvent { uint32_t policyFlags; int32_t deviceId; uint32_t source; - ui::LogicalDisplayId displayId; + ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID; int32_t action; int32_t actionButton; int32_t flags; @@ -108,7 +108,7 @@ struct WindowDispatchArgs { TracedEvent eventEntry; nsecs_t deliveryTime; int32_t resolvedFlags; - gui::Uid targetUid; + gui::Uid targetUid = gui::Uid::INVALID; int64_t vsyncId; int32_t windowId; ui::Transform transform; diff --git a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp index 77b5c2ebcd..ebcd9c986e 100644 --- a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp +++ b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp @@ -34,6 +34,11 @@ namespace { constexpr auto INPUT_EVENT_TRACE_DATA_SOURCE_NAME = "android.input.inputevent"; +using ProtoConverter = + AndroidInputEventProtoConverter<proto::AndroidMotionEvent, proto::AndroidKeyEvent, + proto::AndroidWindowInputDispatchEvent, + proto::AndroidInputEventConfig::Decoder>; + bool isPermanentlyAllowed(gui::Uid uid) { switch (uid.val()) { case AID_SYSTEM: @@ -85,7 +90,7 @@ void PerfettoBackend::InputEventDataSource::OnSetup(const InputEventDataSource:: const auto rawConfig = args.config->android_input_event_config_raw(); auto protoConfig = perfetto::protos::pbzero::AndroidInputEventConfig::Decoder{rawConfig}; - mConfig = AndroidInputEventProtoConverter::parseConfig(protoConfig); + mConfig = ProtoConverter::parseConfig(protoConfig); } void PerfettoBackend::InputEventDataSource::OnStart(const InputEventDataSource::StartArgs&) { @@ -238,7 +243,7 @@ void PerfettoBackend::traceMotionEvent(const TracedMotionEvent& event, auto* inputEvent = winscopeExtensions->set_android_input_event(); auto* dispatchMotion = isRedacted ? inputEvent->set_dispatcher_motion_event_redacted() : inputEvent->set_dispatcher_motion_event(); - AndroidInputEventProtoConverter::toProtoMotionEvent(event, *dispatchMotion, isRedacted); + ProtoConverter::toProtoMotionEvent(event, *dispatchMotion, isRedacted); }); } @@ -266,7 +271,7 @@ void PerfettoBackend::traceKeyEvent(const TracedKeyEvent& event, auto* inputEvent = winscopeExtensions->set_android_input_event(); auto* dispatchKey = isRedacted ? inputEvent->set_dispatcher_key_event_redacted() : inputEvent->set_dispatcher_key_event(); - AndroidInputEventProtoConverter::toProtoKeyEvent(event, *dispatchKey, isRedacted); + ProtoConverter::toProtoKeyEvent(event, *dispatchKey, isRedacted); }); } @@ -295,8 +300,7 @@ void PerfettoBackend::traceWindowDispatch(const WindowDispatchArgs& dispatchArgs auto* dispatchEvent = isRedacted ? inputEvent->set_dispatcher_window_dispatch_event_redacted() : inputEvent->set_dispatcher_window_dispatch_event(); - AndroidInputEventProtoConverter::toProtoWindowDispatchEvent(dispatchArgs, *dispatchEvent, - isRedacted); + ProtoConverter::toProtoWindowDispatchEvent(dispatchArgs, *dispatchEvent, isRedacted); }); } diff --git a/services/inputflinger/docs/device_configuration.md b/services/inputflinger/docs/device_configuration.md new file mode 100644 index 0000000000..0b75eb28bd --- /dev/null +++ b/services/inputflinger/docs/device_configuration.md @@ -0,0 +1,10 @@ +# Input Device Configuration + +There are a number of properties that can be specified for an input device. + +|Property|Value| +|---|----| +|`audio.mic`|A boolean (`0` or `1`) that indicates whether the device has a microphone.| +|`device.additionalSysfsLedsNode`|A string representing the path to search for device lights to be used in addition to searching the device node itself for lights.| +|`device.internal`|A boolean (`0` or `1`) that indicates if this input device is part of the device as opposed to be externally attached.| +|`device.type`|A string representing if the device is of a certain type. Valid values include `rotaryEncoder` and `externalStylus`. diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h index 404a509247..608bec4a0c 100644 --- a/services/inputflinger/include/InputReaderBase.h +++ b/services/inputflinger/include/InputReaderBase.h @@ -143,13 +143,18 @@ struct InputReaderConfiguration { // user's pointer speed setting, should be disabled for mice. This differs from // disabling acceleration via the 'mousePointerAccelerationEnabled' setting, where // the pointer speed setting still influences the scaling factor. - std::set<ui::LogicalDisplayId> displaysWithMousePointerAccelerationDisabled; + std::set<ui::LogicalDisplayId> displaysWithMouseScalingDisabled; // True if the connected mouse should exhibit pointer acceleration. If false, // a flat acceleration curve (linear scaling) is used, but the user's pointer // speed setting still affects the scaling factor. bool mousePointerAccelerationEnabled; + // True if the touchpad should exhibit pointer acceleration. If false, + // a flat acceleration curve (linear scaling) is used, but the user's pointer + // speed setting still affects the scaling factor. + bool touchpadAccelerationEnabled; + // Velocity control parameters for touchpad pointer movements on the old touchpad stack (based // on TouchInputMapper). // @@ -282,8 +287,9 @@ struct InputReaderConfiguration { : virtualKeyQuietTime(0), defaultPointerDisplayId(ui::LogicalDisplayId::DEFAULT), mousePointerSpeed(0), - displaysWithMousePointerAccelerationDisabled(), + displaysWithMouseScalingDisabled(), mousePointerAccelerationEnabled(true), + touchpadAccelerationEnabled(true), pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, static_cast<float>( android::os::IInputConstants:: diff --git a/services/inputflinger/include/NotifyArgs.h b/services/inputflinger/include/NotifyArgs.h index 14487fe04e..c513bfcf50 100644 --- a/services/inputflinger/include/NotifyArgs.h +++ b/services/inputflinger/include/NotifyArgs.h @@ -225,4 +225,6 @@ using NotifyArgs = const char* toString(const NotifyArgs& args); +std::ostream& operator<<(std::ostream& out, const NotifyArgs& args); + } // namespace android diff --git a/services/inputflinger/include/PointerChoreographerPolicyInterface.h b/services/inputflinger/include/PointerChoreographerPolicyInterface.h index 36614b2c95..c805b7459d 100644 --- a/services/inputflinger/include/PointerChoreographerPolicyInterface.h +++ b/services/inputflinger/include/PointerChoreographerPolicyInterface.h @@ -61,6 +61,16 @@ public: /* Notifies that mouse cursor faded due to typing. */ virtual void notifyMouseCursorFadedOnTyping() = 0; + + /** + * Give accessibility a chance to filter motion event by pointer devices. + * The return values denotes the delta x and y after filtering it. + * + * This call happens on the input hot path and it is extremely performance sensitive. + * This also must not call back into native code. + */ + virtual std::optional<vec2> filterPointerMotionForAccessibility( + const vec2& current, const vec2& delta, const ui::LogicalDisplayId& displayId) = 0; }; } // namespace android diff --git a/services/inputflinger/reader/Android.bp b/services/inputflinger/reader/Android.bp index b3cd35c936..dc7f7c1d26 100644 --- a/services/inputflinger/reader/Android.bp +++ b/services/inputflinger/reader/Android.bp @@ -66,9 +66,10 @@ filegroup { "mapper/accumulator/SingleTouchMotionAccumulator.cpp", "mapper/accumulator/TouchButtonAccumulator.cpp", "mapper/gestures/GestureConverter.cpp", - "mapper/gestures/GesturesLogging.cpp", + "mapper/gestures/GesturesLogcatAdapter.cpp", "mapper/gestures/HardwareProperties.cpp", "mapper/gestures/HardwareStateConverter.cpp", + "mapper/gestures/Logging.cpp", "mapper/gestures/PropertyProvider.cpp", "mapper/gestures/TimerProvider.cpp", ], @@ -79,25 +80,25 @@ cc_defaults { srcs: [":libinputreader_sources"], shared_libs: [ "android.companion.virtualdevice.flags-aconfig-cc", + "libPlatformProperties", "libbase", "libcap", "libcrypto", "libcutils", - "libjsoncpp", "libinput", + "libjsoncpp", "liblog", - "libPlatformProperties", "libstatslog", "libstatspull", - "libutils", "libstatssocket", + "libutils", ], static_libs: [ "libchrome-gestures", - "libui-types", "libexpresslog", - "libtextclassifier_hash_static", "libstatslog_express", + "libtextclassifier_hash_static", + "libui-types", ], header_libs: [ "libbatteryservice_headers", diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp index 013ef862ad..2fcb5d831f 100644 --- a/services/inputflinger/reader/EventHub.cpp +++ b/services/inputflinger/reader/EventHub.cpp @@ -351,6 +351,22 @@ static std::optional<std::array<LightColor, COLOR_NUM>> getColorIndexArray( return colors; } +static base::Result<std::shared_ptr<PropertyMap>> loadConfiguration( + const InputDeviceIdentifier& ident) { + std::string configurationFile = + getInputDeviceConfigurationFilePathByDeviceIdentifier(ident, + InputDeviceConfigurationFileType:: + CONFIGURATION); + if (configurationFile.empty()) { + ALOGD("No input device configuration file found for device '%s'.", ident.name.c_str()); + return base::Result<std::shared_ptr<PropertyMap>>(nullptr); + } + base::Result<std::shared_ptr<PropertyMap>> propertyMap = + PropertyMap::load(configurationFile.c_str()); + + return propertyMap; +} + /** * Read country code information exposed through the sysfs path and convert it to Layout info. */ @@ -409,11 +425,22 @@ static std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> readBatteryConf * Read information about lights exposed through the sysfs path. */ static std::unordered_map<int32_t /*lightId*/, RawLightInfo> readLightsConfiguration( - const std::filesystem::path& sysfsRootPath) { + const std::filesystem::path& sysfsRootPath, const std::shared_ptr<PropertyMap>& config) { std::unordered_map<int32_t, RawLightInfo> lightInfos; int32_t nextLightId = 0; - // Check if device has any lights. - const auto& paths = findSysfsNodes(sysfsRootPath, SysfsClass::LEDS); + // Check if device has any lights. If the Input Device Configuration file specifies any lights, + // use those in addition to searching the device node itself for lights. + std::vector<std::filesystem::path> paths = findSysfsNodes(sysfsRootPath, SysfsClass::LEDS); + + if (config) { + auto additionalLights = config->getString("device.additionalSysfsLedsNode"); + if (additionalLights) { + ALOGI("IDC specifies additional path for lights at '%s'", + additionalLights.value().c_str()); + paths.push_back(std::filesystem::path(additionalLights.value())); + } + } + for (const auto& nodePath : paths) { RawLightInfo info; info.id = ++nextLightId; @@ -532,17 +559,16 @@ std::ostream& operator<<(std::ostream& out, const std::optional<RawAbsoluteAxisI // --- EventHub::Device --- EventHub::Device::Device(int fd, int32_t id, std::string path, InputDeviceIdentifier identifier, - std::shared_ptr<const AssociatedDevice> assocDev) + std::shared_ptr<PropertyMap> config) : fd(fd), id(id), path(std::move(path)), identifier(std::move(identifier)), classes(0), - configuration(nullptr), + configuration(std::move(config)), virtualKeyMap(nullptr), ffEffectPlaying(false), ffEffectId(-1), - associatedDevice(std::move(assocDev)), controllerNumber(0), enabled(true), isVirtual(fd < 0), @@ -696,26 +722,6 @@ bool EventHub::Device::hasKeycodeInternalLocked(int keycode) const { return false; } -void EventHub::Device::loadConfigurationLocked() { - configurationFile = - getInputDeviceConfigurationFilePathByDeviceIdentifier(identifier, - InputDeviceConfigurationFileType:: - CONFIGURATION); - if (configurationFile.empty()) { - ALOGD("No input device configuration file found for device '%s'.", identifier.name.c_str()); - } else { - android::base::Result<std::unique_ptr<PropertyMap>> propertyMap = - PropertyMap::load(configurationFile.c_str()); - if (!propertyMap.ok()) { - ALOGE("Error loading input device configuration file for device '%s'. " - "Using default configuration.", - identifier.name.c_str()); - } else { - configuration = std::move(*propertyMap); - } - } -} - bool EventHub::Device::loadVirtualKeyMapLocked() { // The virtual key map is supplied by the kernel as a system board property file. std::string propPath = "/sys/board_properties/virtualkeys."; @@ -1611,7 +1617,7 @@ void EventHub::assignDescriptorLocked(InputDeviceIdentifier& identifier) { } std::shared_ptr<const EventHub::AssociatedDevice> EventHub::obtainAssociatedDeviceLocked( - const std::filesystem::path& devicePath) const { + const std::filesystem::path& devicePath, const std::shared_ptr<PropertyMap>& config) const { const std::optional<std::filesystem::path> sysfsRootPathOpt = getSysfsRootPath(devicePath.c_str()); if (!sysfsRootPathOpt) { @@ -1620,41 +1626,50 @@ std::shared_ptr<const EventHub::AssociatedDevice> EventHub::obtainAssociatedDevi const auto& path = *sysfsRootPathOpt; - std::shared_ptr<const AssociatedDevice> associatedDevice = std::make_shared<AssociatedDevice>( - AssociatedDevice{.sysfsRootPath = path, - .batteryInfos = readBatteryConfiguration(path), - .lightInfos = readLightsConfiguration(path), - .layoutInfo = readLayoutConfiguration(path)}); - - bool associatedDeviceChanged = false; + std::shared_ptr<const AssociatedDevice> associatedDevice; for (const auto& [id, dev] : mDevices) { - if (dev->associatedDevice && dev->associatedDevice->sysfsRootPath == path) { - if (*associatedDevice != *dev->associatedDevice) { - associatedDeviceChanged = true; - dev->associatedDevice = associatedDevice; - } + if (!dev->associatedDevice || dev->associatedDevice->sysfsRootPath != path) { + continue; + } + if (!associatedDevice) { + // Found matching associated device for the first time. associatedDevice = dev->associatedDevice; + // Reload this associated device if needed. Use the base device + // config. Note that this will essentially arbitrarily pick one + // Device as the base for the AssociatedDevice configuration. If + // there are multiple Device's that have a configuration for the + // AssociatedDevice, only one configuration will be chosen and will + // be used for all other AssociatedDevices for the same sysfs path. + const auto reloadedDevice = AssociatedDevice(path, associatedDevice->baseDevConfig); + if (reloadedDevice != *dev->associatedDevice) { + ALOGI("The AssociatedDevice changed for path '%s'. Using new AssociatedDevice: %s", + path.c_str(), associatedDevice->dump().c_str()); + associatedDevice = std::make_shared<AssociatedDevice>(std::move(reloadedDevice)); + } } + // Update the associatedDevice. + dev->associatedDevice = associatedDevice; + } + + if (!associatedDevice) { + // No existing associated device found for this path, so create a new one. + associatedDevice = std::make_shared<AssociatedDevice>(path, config); } - ALOGI_IF(associatedDeviceChanged, - "The AssociatedDevice changed for path '%s'. Using new AssociatedDevice: %s", - path.c_str(), associatedDevice->dump().c_str()); return associatedDevice; } -bool EventHub::AssociatedDevice::isChanged() const { - std::unordered_map<int32_t, RawBatteryInfo> newBatteryInfos = - readBatteryConfiguration(sysfsRootPath); - std::unordered_map<int32_t, RawLightInfo> newLightInfos = - readLightsConfiguration(sysfsRootPath); - std::optional<RawLayoutInfo> newLayoutInfo = readLayoutConfiguration(sysfsRootPath); +EventHub::AssociatedDevice::AssociatedDevice(const std::filesystem::path& sysfsRootPath, + std::shared_ptr<PropertyMap> config) + : sysfsRootPath(sysfsRootPath), + baseDevConfig(std::move(config)), + batteryInfos(readBatteryConfiguration(sysfsRootPath)), + lightInfos(readLightsConfiguration(sysfsRootPath, baseDevConfig)), + layoutInfo(readLayoutConfiguration(sysfsRootPath)) {} - if (newBatteryInfos == batteryInfos && newLightInfos == lightInfos && - newLayoutInfo == layoutInfo) { - return false; - } - return true; +std::string EventHub::AssociatedDevice::dump() const { + return StringPrintf("path=%s, numBatteries=%zu, numLight=%zu", sysfsRootPath.c_str(), + batteryInfos.size(), lightInfos.size()); } void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) { @@ -2335,11 +2350,21 @@ void EventHub::openDeviceLocked(const std::string& devicePath) { // Fill in the descriptor. assignDescriptorLocked(identifier); + // Load the configuration file for the device. + std::shared_ptr<PropertyMap> configuration = nullptr; + base::Result<std::shared_ptr<PropertyMap>> propertyMapResult = loadConfiguration(identifier); + if (!propertyMapResult.ok()) { + ALOGE("Error loading input device configuration file for device '%s'. " + "Using default configuration. Error: %s", + identifier.name.c_str(), propertyMapResult.error().message().c_str()); + } else { + configuration = propertyMapResult.value(); + } + // Allocate device. (The device object takes ownership of the fd at this point.) int32_t deviceId = mNextDeviceId++; std::unique_ptr<Device> device = - std::make_unique<Device>(fd, deviceId, devicePath, identifier, - obtainAssociatedDeviceLocked(devicePath)); + std::make_unique<Device>(fd, deviceId, devicePath, identifier, configuration); ALOGV("add device %d: %s\n", deviceId, devicePath.c_str()); ALOGV(" bus: %04x\n" @@ -2354,8 +2379,8 @@ void EventHub::openDeviceLocked(const std::string& devicePath) { ALOGV(" driver: v%d.%d.%d\n", driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff); - // Load the configuration file for the device. - device->loadConfigurationLocked(); + // Obtain the associated device, if any. + device->associatedDevice = obtainAssociatedDeviceLocked(devicePath, device->configuration); // Figure out the kinds of events the device reports. device->readDeviceBitMask(EVIOCGBIT(EV_KEY, 0), device->keyBitmask); @@ -2646,33 +2671,57 @@ status_t EventHub::disableDevice(int32_t deviceId) { void EventHub::sysfsNodeChanged(const std::string& sysfsNodePath) { std::scoped_lock _l(mLock); - // Check in opening devices - for (auto it = mOpeningDevices.begin(); it != mOpeningDevices.end(); it++) { - std::unique_ptr<Device>& device = *it; - if (device->associatedDevice && - sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) != - std::string::npos && - device->associatedDevice->isChanged()) { - it = mOpeningDevices.erase(it); - openDeviceLocked(device->path); + // Testing whether a sysfs node changed involves several syscalls, so use a cache to avoid + // testing the same node multiple times. + std::map<std::shared_ptr<const AssociatedDevice>, bool /*changed*/> testedDevices; + auto isAssociatedDeviceChanged = [&testedDevices, &sysfsNodePath](const Device& dev) { + if (!dev.associatedDevice) { + return false; } - } + if (auto testedIt = testedDevices.find(dev.associatedDevice); + testedIt != testedDevices.end()) { + return testedIt->second; + } + // Cache miss + if (sysfsNodePath.find(dev.associatedDevice->sysfsRootPath.string()) == std::string::npos) { + testedDevices.emplace(dev.associatedDevice, false); + return false; + } + auto reloadedDevice = AssociatedDevice(dev.associatedDevice->sysfsRootPath, + dev.associatedDevice->baseDevConfig); + const bool changed = *dev.associatedDevice != reloadedDevice; + testedDevices.emplace(dev.associatedDevice, changed); + return changed; + }; + + std::set<Device*> devicesToClose; + std::set<std::string /*path*/> devicesToOpen; + + // Check in opening devices. If its associated device changed, + // the device should be removed from mOpeningDevices and needs to be opened again. + std::erase_if(mOpeningDevices, [&](const auto& dev) { + if (isAssociatedDeviceChanged(*dev)) { + devicesToOpen.emplace(dev->path); + return true; + } + return false; + }); - // Check in already added device - std::vector<Device*> devicesToReopen; - for (const auto& [id, device] : mDevices) { - if (device->associatedDevice && - sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) != - std::string::npos && - device->associatedDevice->isChanged()) { - devicesToReopen.push_back(device.get()); + // Check in already added device. If its associated device changed, + // the device needs to be re-opened. + for (const auto& [id, dev] : mDevices) { + if (isAssociatedDeviceChanged(*dev)) { + devicesToOpen.emplace(dev->path); + devicesToClose.emplace(dev.get()); } } - for (const auto& device : devicesToReopen) { + + for (auto* device : devicesToClose) { closeDeviceLocked(*device); - openDeviceLocked(device->path); } - devicesToReopen.clear(); + for (const auto& path : devicesToOpen) { + openDeviceLocked(path); + } } void EventHub::createVirtualKeyboardLocked() { @@ -2972,9 +3021,4 @@ void EventHub::monitor() const { std::unique_lock<std::mutex> lock(mLock); } -std::string EventHub::AssociatedDevice::dump() const { - return StringPrintf("path=%s, numBatteries=%zu, numLight=%zu", sysfsRootPath.c_str(), - batteryInfos.size(), lightInfos.size()); -} - } // namespace android diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index 24919b678d..58df692b3e 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -32,6 +32,7 @@ #include <unistd.h> #include <utils/Errors.h> #include <utils/Thread.h> +#include <string> #include "InputDevice.h" #include "include/gestures.h" @@ -62,6 +63,28 @@ bool isSubDevice(const InputDeviceIdentifier& identifier1, identifier1.location == identifier2.location); } +/** + * Determines if the device classes passed for two devices represent incompatible combinations + * that should not be merged into into a single InputDevice. + */ + +bool isCompatibleSubDevice(ftl::Flags<InputDeviceClass> classes1, + ftl::Flags<InputDeviceClass> classes2) { + if (!com::android::input::flags::prevent_merging_input_pointer_devices()) { + return true; + } + + const ftl::Flags<InputDeviceClass> pointerFlags = + ftl::Flags<InputDeviceClass>{InputDeviceClass::TOUCH, InputDeviceClass::TOUCH_MT, + InputDeviceClass::CURSOR, InputDeviceClass::TOUCHPAD}; + + // Do not merge devices that both have any type of pointer event. + if (classes1.any(pointerFlags) && classes2.any(pointerFlags)) return false; + + // Safe to merge + return true; +} + bool isStylusPointerGestureStart(const NotifyMotionArgs& motionArgs) { const auto actionMasked = MotionEvent::getActionMasked(motionArgs.action); if (actionMasked != AMOTION_EVENT_ACTION_HOVER_ENTER && @@ -174,9 +197,8 @@ void InputReader::loopOnce() { if (mNextTimeout != LLONG_MAX) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); if (now >= mNextTimeout) { - if (debugRawEvents()) { - ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f); - } + ALOGD_IF(debugRawEvents(), "Timeout expired, latency=%0.3fms", + (now - mNextTimeout) * 0.000001f); mNextTimeout = LLONG_MAX; mPendingArgs += timeoutExpiredLocked(now); } @@ -241,9 +263,7 @@ std::list<NotifyArgs> InputReader::processEventsLocked(const RawEvent* rawEvents } batchSize += 1; } - if (debugRawEvents()) { - ALOGD("BatchSize: %zu Count: %zu", batchSize, count); - } + ALOGD_IF(debugRawEvents(), "BatchSize: %zu Count: %zu", batchSize, count); out += processEventsForDeviceLocked(deviceId, rawEvent, batchSize); } else { switch (rawEvent->type) { @@ -271,7 +291,8 @@ void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) { } InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId); - std::shared_ptr<InputDevice> device = createDeviceLocked(when, eventHubId, identifier); + ftl::Flags<InputDeviceClass> classes = mEventHub->getDeviceClasses(eventHubId); + std::shared_ptr<InputDevice> device = createDeviceLocked(when, eventHubId, identifier, classes); mPendingArgs += device->configure(when, mConfig, /*changes=*/{}); mPendingArgs += device->reset(when); @@ -354,12 +375,16 @@ void InputReader::removeDeviceLocked(nsecs_t when, int32_t eventHubId) { } std::shared_ptr<InputDevice> InputReader::createDeviceLocked( - nsecs_t when, int32_t eventHubId, const InputDeviceIdentifier& identifier) { - auto deviceIt = std::find_if(mDevices.begin(), mDevices.end(), [identifier](auto& devicePair) { - const InputDeviceIdentifier identifier2 = - devicePair.second->getDeviceInfo().getIdentifier(); - return isSubDevice(identifier, identifier2); - }); + nsecs_t when, int32_t eventHubId, const InputDeviceIdentifier& identifier, + ftl::Flags<InputDeviceClass> classes) { + auto deviceIt = + std::find_if(mDevices.begin(), mDevices.end(), [identifier, classes](auto& devicePair) { + const InputDeviceIdentifier identifier2 = + devicePair.second->getDeviceInfo().getIdentifier(); + const ftl::Flags<InputDeviceClass> classes2 = devicePair.second->getClasses(); + return isSubDevice(identifier, identifier2) && + isCompatibleSubDevice(classes, classes2); + }); std::shared_ptr<InputDevice> device; if (deviceIt != mDevices.end()) { @@ -921,7 +946,10 @@ bool InputReader::setKernelWakeEnabled(int32_t deviceId, bool enabled) { void InputReader::dump(std::string& dump) { std::scoped_lock _l(mLock); + dumpLocked(dump); +} +void InputReader::dumpLocked(std::string& dump) { mEventHub->dump(dump); dump += "\n"; @@ -1008,6 +1036,12 @@ void InputReader::monitor() { InputReader::ContextImpl::ContextImpl(InputReader* reader) : mReader(reader), mIdGenerator(IdGenerator::Source::INPUT_READER) {} +std::string InputReader::ContextImpl::dump() { + std::string dump; + mReader->dumpLocked(dump); + return dump; +} + void InputReader::ContextImpl::updateGlobalMetaState() { // lock is already held by the input loop mReader->updateGlobalMetaStateLocked(); @@ -1085,7 +1119,7 @@ EventHubInterface* InputReader::ContextImpl::getEventHub() { return mReader->mEventHub.get(); } -int32_t InputReader::ContextImpl::getNextId() { +int32_t InputReader::ContextImpl::getNextId() const { return mIdGenerator.nextId(); } diff --git a/services/inputflinger/reader/controller/PeripheralController.cpp b/services/inputflinger/reader/controller/PeripheralController.cpp index 7434ae4b0a..df22890319 100644 --- a/services/inputflinger/reader/controller/PeripheralController.cpp +++ b/services/inputflinger/reader/controller/PeripheralController.cpp @@ -78,10 +78,8 @@ std::optional<std::int32_t> PeripheralController::Light::getRawLightBrightness(i if (rawMaxBrightness != MAX_BRIGHTNESS) { brightness = brightness * ratio; } - if (DEBUG_LIGHT_DETAILS) { - ALOGD("getRawLightBrightness rawLightId %d brightness 0x%x ratio %.2f", rawLightId, - brightness, ratio); - } + ALOGD_IF(DEBUG_LIGHT_DETAILS, "getRawLightBrightness rawLightId %d brightness 0x%x ratio %.2f", + rawLightId, brightness, ratio); return brightness; } @@ -97,10 +95,8 @@ void PeripheralController::Light::setRawLightBrightness(int32_t rawLightId, int3 if (rawMaxBrightness != MAX_BRIGHTNESS) { brightness = ceil(brightness / ratio); } - if (DEBUG_LIGHT_DETAILS) { - ALOGD("setRawLightBrightness rawLightId %d brightness 0x%x ratio %.2f", rawLightId, - brightness, ratio); - } + ALOGD_IF(DEBUG_LIGHT_DETAILS, "setRawLightBrightness rawLightId %d brightness 0x%x ratio %.2f", + rawLightId, brightness, ratio); context.setLightBrightness(rawLightId, brightness); } @@ -453,10 +449,9 @@ void PeripheralController::configureLights() { if (rawInfo->flags.test(InputLightClass::GLOBAL)) { rawGlobalId = rawId; } - if (DEBUG_LIGHT_DETAILS) { - ALOGD("Light rawId %d name %s max %d flags %s \n", rawInfo->id, rawInfo->name.c_str(), - rawInfo->maxBrightness.value_or(MAX_BRIGHTNESS), rawInfo->flags.string().c_str()); - } + ALOGD_IF(DEBUG_LIGHT_DETAILS, "Light rawId %d name %s max %d flags %s\n", rawInfo->id, + rawInfo->name.c_str(), rawInfo->maxBrightness.value_or(MAX_BRIGHTNESS), + rawInfo->flags.string().c_str()); } // Construct a player ID light @@ -473,10 +468,8 @@ void PeripheralController::configureLights() { } // Construct a RGB light for composed RGB light if (hasRedLed && hasGreenLed && hasBlueLed) { - if (DEBUG_LIGHT_DETAILS) { - ALOGD("Rgb light ids [%d, %d, %d] \n", rawRgbIds.at(LightColor::RED), - rawRgbIds.at(LightColor::GREEN), rawRgbIds.at(LightColor::BLUE)); - } + ALOGD_IF(DEBUG_LIGHT_DETAILS, "Rgb light ids [%d, %d, %d]\n", rawRgbIds.at(LightColor::RED), + rawRgbIds.at(LightColor::GREEN), rawRgbIds.at(LightColor::BLUE)); bool isKeyboardBacklight = keyboardBacklightIds.find(rawRgbIds.at(LightColor::RED)) != keyboardBacklightIds.end() && keyboardBacklightIds.find(rawRgbIds.at(LightColor::GREEN)) != @@ -518,9 +511,8 @@ void PeripheralController::configureLights() { // If the node is multi-color led, construct a MULTI_COLOR light if (rawInfo.flags.test(InputLightClass::MULTI_INDEX) && rawInfo.flags.test(InputLightClass::MULTI_INTENSITY)) { - if (DEBUG_LIGHT_DETAILS) { - ALOGD("Multicolor light Id %d name %s \n", rawInfo.id, rawInfo.name.c_str()); - } + ALOGD_IF(DEBUG_LIGHT_DETAILS, "Multicolor light Id %d name %s\n", rawInfo.id, + rawInfo.name.c_str()); std::unique_ptr<Light> light = std::make_unique<MultiColorLight>(getDeviceContext(), rawInfo.name, ++mNextId, type, rawInfo.id); @@ -528,9 +520,8 @@ void PeripheralController::configureLights() { continue; } // Construct a Mono LED light - if (DEBUG_LIGHT_DETAILS) { - ALOGD("Mono light Id %d name %s \n", rawInfo.id, rawInfo.name.c_str()); - } + ALOGD_IF(DEBUG_LIGHT_DETAILS, "Mono light Id %d name %s\n", rawInfo.id, + rawInfo.name.c_str()); std::unique_ptr<Light> light = std::make_unique<MonoLight>(getDeviceContext(), rawInfo.name, ++mNextId, type, rawInfo.id); @@ -552,10 +543,8 @@ bool PeripheralController::setLightColor(int32_t lightId, int32_t color) { return false; } auto& light = it->second; - if (DEBUG_LIGHT_DETAILS) { - ALOGD("setLightColor lightId %d type %s color 0x%x", lightId, - ftl::enum_string(light->type).c_str(), color); - } + ALOGD_IF(DEBUG_LIGHT_DETAILS, "setLightColor lightId %d type %s color 0x%x", lightId, + ftl::enum_string(light->type).c_str(), color); return light->setLightColor(color); } @@ -566,10 +555,8 @@ std::optional<int32_t> PeripheralController::getLightColor(int32_t lightId) { } auto& light = it->second; std::optional<int32_t> color = light->getLightColor(); - if (DEBUG_LIGHT_DETAILS) { - ALOGD("getLightColor lightId %d type %s color 0x%x", lightId, - ftl::enum_string(light->type).c_str(), color.value_or(0)); - } + ALOGD_IF(DEBUG_LIGHT_DETAILS, "getLightColor lightId %d type %s color 0x%x", lightId, + ftl::enum_string(light->type).c_str(), color.value_or(0)); return color; } diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h index 5839b4c41c..adbfdebfb0 100644 --- a/services/inputflinger/reader/include/EventHub.h +++ b/services/inputflinger/reader/include/EventHub.h @@ -21,6 +21,7 @@ #include <filesystem> #include <functional> #include <map> +#include <memory> #include <optional> #include <ostream> #include <string> @@ -87,6 +88,7 @@ std::ostream& operator<<(std::ostream& out, const std::optional<RawAbsoluteAxisI * If any new classes are added, we need to add them in rust input side too. */ enum class InputDeviceClass : uint32_t { + // LINT.IfChange /* The input device is a keyboard or has buttons. */ KEYBOARD = android::os::IInputConstants::DEVICE_CLASS_KEYBOARD, @@ -143,6 +145,7 @@ enum class InputDeviceClass : uint32_t { /* The input device is external (not built-in). */ EXTERNAL = android::os::IInputConstants::DEVICE_CLASS_EXTERNAL, + // LINT.ThenChange(frameworks/native/services/inputflinger/tests/fuzzers/MapperHelpers.h) }; enum class SysfsClass : uint32_t { @@ -619,13 +622,16 @@ public: private: // Holds information about the sysfs device associated with the Device. struct AssociatedDevice { + AssociatedDevice(const std::filesystem::path& sysfsRootPath, + std::shared_ptr<PropertyMap> baseDevConfig); // The sysfs root path of the misc device. std::filesystem::path sysfsRootPath; + // The configuration of the base device. + std::shared_ptr<PropertyMap> baseDevConfig; std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> batteryInfos; std::unordered_map<int32_t /*lightId*/, RawLightInfo> lightInfos; std::optional<RawLayoutInfo> layoutInfo; - bool isChanged() const; bool operator==(const AssociatedDevice&) const = default; bool operator!=(const AssociatedDevice&) const = default; std::string dump() const; @@ -658,7 +664,7 @@ private: std::map<int /*axis*/, AxisState> absState; std::string configurationFile; - std::unique_ptr<PropertyMap> configuration; + std::shared_ptr<PropertyMap> configuration; std::unique_ptr<VirtualKeyMap> virtualKeyMap; KeyMap keyMap; @@ -672,7 +678,7 @@ private: int32_t controllerNumber; Device(int fd, int32_t id, std::string path, InputDeviceIdentifier identifier, - std::shared_ptr<const AssociatedDevice> assocDev); + std::shared_ptr<PropertyMap> config); ~Device(); void close(); @@ -692,7 +698,6 @@ private: void populateAbsoluteAxisStates(); bool hasKeycodeLocked(int keycode) const; bool hasKeycodeInternalLocked(int keycode) const; - void loadConfigurationLocked(); bool loadVirtualKeyMapLocked(); status_t loadKeyMapLocked(); bool isExternalDeviceLocked(); @@ -724,7 +729,8 @@ private: void addDeviceLocked(std::unique_ptr<Device> device) REQUIRES(mLock); void assignDescriptorLocked(InputDeviceIdentifier& identifier) REQUIRES(mLock); std::shared_ptr<const AssociatedDevice> obtainAssociatedDeviceLocked( - const std::filesystem::path& devicePath) const REQUIRES(mLock); + const std::filesystem::path& devicePath, + const std::shared_ptr<PropertyMap>& config) const REQUIRES(mLock); void closeDeviceByPathLocked(const std::string& devicePath) REQUIRES(mLock); void closeVideoDeviceByPathLocked(const std::string& devicePath) REQUIRES(mLock); diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h index 1403ca2986..6a259373df 100644 --- a/services/inputflinger/reader/include/InputReader.h +++ b/services/inputflinger/reader/include/InputReader.h @@ -21,10 +21,12 @@ #include <utils/Mutex.h> #include <memory> +#include <string> #include <unordered_map> #include <vector> #include "EventHub.h" +#include "InputDevice.h" #include "InputListener.h" #include "InputReaderBase.h" #include "InputReaderContext.h" @@ -127,7 +129,8 @@ public: protected: // These members are protected so they can be instrumented by test cases. virtual std::shared_ptr<InputDevice> createDeviceLocked(nsecs_t when, int32_t deviceId, - const InputDeviceIdentifier& identifier) + const InputDeviceIdentifier& identifier, + ftl::Flags<InputDeviceClass> classes) REQUIRES(mLock); // With each iteration of the loop, InputReader reads and processes one incoming message from @@ -140,6 +143,7 @@ protected: public: explicit ContextImpl(InputReader* reader); + std::string dump() REQUIRES(mReader->mLock) override; // lock is already held by the input loop void updateGlobalMetaState() NO_THREAD_SAFETY_ANALYSIS override; int32_t getGlobalMetaState() NO_THREAD_SAFETY_ANALYSIS override; @@ -154,7 +158,7 @@ protected: REQUIRES(mReader->mLock) override; InputReaderPolicyInterface* getPolicy() REQUIRES(mReader->mLock) override; EventHubInterface* getEventHub() REQUIRES(mReader->mLock) override; - int32_t getNextId() NO_THREAD_SAFETY_ANALYSIS override; + int32_t getNextId() const NO_THREAD_SAFETY_ANALYSIS override; void updateLedMetaState(int32_t metaState) REQUIRES(mReader->mLock) override; int32_t getLedMetaState() REQUIRES(mReader->mLock) REQUIRES(mLock) override; void setPreventingTouchpadTaps(bool prevent) REQUIRES(mReader->mLock) @@ -214,6 +218,8 @@ private: // The input device that produced a new gesture most recently. DeviceId mLastUsedDeviceId GUARDED_BY(mLock){ReservedInputDeviceId::INVALID_INPUT_DEVICE_ID}; + void dumpLocked(std::string& dump) REQUIRES(mLock); + // low-level input event decoding and device management [[nodiscard]] std::list<NotifyArgs> processEventsLocked(const RawEvent* rawEvents, size_t count) REQUIRES(mLock); diff --git a/services/inputflinger/reader/include/InputReaderContext.h b/services/inputflinger/reader/include/InputReaderContext.h index e0e0ac2051..f38fd7b8ac 100644 --- a/services/inputflinger/reader/include/InputReaderContext.h +++ b/services/inputflinger/reader/include/InputReaderContext.h @@ -20,6 +20,7 @@ #include <input/KeyboardClassifier.h> #include "NotifyArgs.h" +#include <string> #include <vector> namespace android { @@ -39,6 +40,8 @@ public: InputReaderContext() {} virtual ~InputReaderContext() {} + virtual std::string dump() = 0; + virtual void updateGlobalMetaState() = 0; virtual int32_t getGlobalMetaState() = 0; @@ -55,7 +58,7 @@ public: virtual InputReaderPolicyInterface* getPolicy() = 0; virtual EventHubInterface* getEventHub() = 0; - virtual int32_t getNextId() = 0; + virtual int32_t getNextId() const = 0; virtual void updateLedMetaState(int32_t metaState) = 0; virtual int32_t getLedMetaState() = 0; diff --git a/services/inputflinger/reader/mapper/CapturedTouchpadEventConverter.cpp b/services/inputflinger/reader/mapper/CapturedTouchpadEventConverter.cpp index dd46bbc543..d796af158b 100644 --- a/services/inputflinger/reader/mapper/CapturedTouchpadEventConverter.cpp +++ b/services/inputflinger/reader/mapper/CapturedTouchpadEventConverter.cpp @@ -25,8 +25,6 @@ #include <linux/input-event-codes.h> #include <log/log_main.h> -namespace input_flags = com::android::input::flags; - namespace android { namespace { @@ -119,15 +117,10 @@ std::string CapturedTouchpadEventConverter::dump() const { } void CapturedTouchpadEventConverter::populateMotionRanges(InputDeviceInfo& info) const { - if (input_flags::include_relative_axis_values_for_captured_touchpads()) { - tryAddRawMotionRangeWithRelative(/*byref*/ info, AMOTION_EVENT_AXIS_X, - AMOTION_EVENT_AXIS_RELATIVE_X, ABS_MT_POSITION_X); - tryAddRawMotionRangeWithRelative(/*byref*/ info, AMOTION_EVENT_AXIS_Y, - AMOTION_EVENT_AXIS_RELATIVE_Y, ABS_MT_POSITION_Y); - } else { - tryAddRawMotionRange(/*byref*/ info, AMOTION_EVENT_AXIS_X, ABS_MT_POSITION_X); - tryAddRawMotionRange(/*byref*/ info, AMOTION_EVENT_AXIS_Y, ABS_MT_POSITION_Y); - } + tryAddRawMotionRangeWithRelative(/*byref*/ info, AMOTION_EVENT_AXIS_X, + AMOTION_EVENT_AXIS_RELATIVE_X, ABS_MT_POSITION_X); + tryAddRawMotionRangeWithRelative(/*byref*/ info, AMOTION_EVENT_AXIS_Y, + AMOTION_EVENT_AXIS_RELATIVE_Y, ABS_MT_POSITION_Y); tryAddRawMotionRange(/*byref*/ info, AMOTION_EVENT_AXIS_TOUCH_MAJOR, ABS_MT_TOUCH_MAJOR); tryAddRawMotionRange(/*byref*/ info, AMOTION_EVENT_AXIS_TOUCH_MINOR, ABS_MT_TOUCH_MINOR); tryAddRawMotionRange(/*byref*/ info, AMOTION_EVENT_AXIS_TOOL_MAJOR, ABS_MT_WIDTH_MAJOR); @@ -213,13 +206,11 @@ std::list<NotifyArgs> CapturedTouchpadEventConverter::sync(nsecs_t when, nsecs_t } out.push_back( makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_MOVE, coords, properties)); - if (input_flags::include_relative_axis_values_for_captured_touchpads()) { - // For any further events we send from this sync, the pointers won't have moved relative - // to the positions we just reported in this MOVE event, so zero out the relative axes. - for (PointerCoords& pointer : coords) { - pointer.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0); - pointer.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0); - } + // For any further events we send from this sync, the pointers won't have moved relative to + // the positions we just reported in this MOVE event, so zero out the relative axes. + for (PointerCoords& pointer : coords) { + pointer.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0); + pointer.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0); } } @@ -275,9 +266,7 @@ std::list<NotifyArgs> CapturedTouchpadEventConverter::sync(nsecs_t when, nsecs_t /*flags=*/cancel ? AMOTION_EVENT_FLAG_CANCELED : 0)); freePointerIdForSlot(slotNumber); - if (input_flags::include_relative_axis_values_for_captured_touchpads()) { - mPreviousCoordsForSlotNumber.erase(slotNumber); - } + mPreviousCoordsForSlotNumber.erase(slotNumber); coords.erase(coords.begin() + indexToRemove); properties.erase(properties.begin() + indexToRemove); // Now that we've removed some coords and properties, we might have to update the slot @@ -336,15 +325,13 @@ PointerCoords CapturedTouchpadEventConverter::makePointerCoordsForSlot(size_t sl coords.clear(); coords.setAxisValue(AMOTION_EVENT_AXIS_X, slot.getX()); coords.setAxisValue(AMOTION_EVENT_AXIS_Y, slot.getY()); - if (input_flags::include_relative_axis_values_for_captured_touchpads()) { - if (auto it = mPreviousCoordsForSlotNumber.find(slotNumber); - it != mPreviousCoordsForSlotNumber.end()) { - auto [oldX, oldY] = it->second; - coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, slot.getX() - oldX); - coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, slot.getY() - oldY); - } - mPreviousCoordsForSlotNumber[slotNumber] = std::make_pair(slot.getX(), slot.getY()); + if (auto it = mPreviousCoordsForSlotNumber.find(slotNumber); + it != mPreviousCoordsForSlotNumber.end()) { + auto [oldX, oldY] = it->second; + coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, slot.getX() - oldX); + coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, slot.getY() - oldY); } + mPreviousCoordsForSlotNumber[slotNumber] = std::make_pair(slot.getX(), slot.getY()); coords.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, slot.getTouchMajor()); coords.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, slot.getTouchMinor()); diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index e9f17e796f..e21c2f9120 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp @@ -419,7 +419,7 @@ int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCod } } -std::optional<ui::LogicalDisplayId> CursorInputMapper::getAssociatedDisplayId() { +std::optional<ui::LogicalDisplayId> CursorInputMapper::getAssociatedDisplayId() const { return mDisplayId; } @@ -484,7 +484,7 @@ void CursorInputMapper::configureOnChangePointerSpeed(const InputReaderConfigura return; } - bool disableAllScaling = config.displaysWithMousePointerAccelerationDisabled.count( + bool disableAllScaling = config.displaysWithMouseScalingDisabled.count( mDisplayId.value_or(ui::LogicalDisplayId::INVALID)) != 0; mPointerVelocityControl.setAccelerationEnabled(!disableAllScaling); diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h index 83199227b1..f2b2b6f2a8 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.h +++ b/services/inputflinger/reader/mapper/CursorInputMapper.h @@ -63,7 +63,7 @@ public: virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override; - virtual std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() override; + virtual std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() const override; private: // Amount that trackball needs to move in order to generate a key event. @@ -115,6 +115,7 @@ private: ui::Rotation mOrientation{ui::ROTATION_0}; FloatRect mBoundsInLogicalDisplay{}; + // The button state as of the last sync. int32_t mButtonState; nsecs_t mDownTime; nsecs_t mLastEventTime; diff --git a/services/inputflinger/reader/mapper/InputMapper.h b/services/inputflinger/reader/mapper/InputMapper.h index d4a86acd79..630c3d9e93 100644 --- a/services/inputflinger/reader/mapper/InputMapper.h +++ b/services/inputflinger/reader/mapper/InputMapper.h @@ -66,11 +66,12 @@ public: virtual ~InputMapper(); - inline int32_t getDeviceId() { return mDeviceContext.getId(); } + inline int32_t getDeviceId() const { return mDeviceContext.getId(); } inline InputDeviceContext& getDeviceContext() { return mDeviceContext; } inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }; inline const std::string getDeviceName() const { return mDeviceContext.getName(); } inline InputReaderContext* getContext() { return mDeviceContext.getContext(); } + inline const InputReaderContext* getContext() const { return mDeviceContext.getContext(); } inline InputReaderPolicyInterface* getPolicy() { return getContext()->getPolicy(); } virtual uint32_t getSources() const = 0; @@ -114,7 +115,9 @@ public: [[nodiscard]] virtual std::list<NotifyArgs> updateExternalStylusState(const StylusState& state); - virtual std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() { return std::nullopt; } + virtual std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() const { + return std::nullopt; + } virtual void updateLedState(bool reset) {} virtual std::optional<HardwareProperties> getTouchpadHardwareProperties(); diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp index fe3e4c29e5..400792bc60 100644 --- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp +++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp @@ -104,14 +104,14 @@ uint32_t KeyboardInputMapper::getSources() const { return mMapperSource; } -ui::Rotation KeyboardInputMapper::getOrientation() { +ui::Rotation KeyboardInputMapper::getOrientation() const { if (mViewport) { return mViewport->orientation; } return ui::ROTATION_0; } -ui::LogicalDisplayId KeyboardInputMapper::getDisplayId() { +ui::LogicalDisplayId KeyboardInputMapper::getDisplayId() const { if (mViewport) { return mViewport->displayId; } @@ -471,7 +471,7 @@ void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState, int32_t } } -std::optional<ui::LogicalDisplayId> KeyboardInputMapper::getAssociatedDisplayId() { +std::optional<ui::LogicalDisplayId> KeyboardInputMapper::getAssociatedDisplayId() const { if (mViewport) { return std::make_optional(mViewport->displayId); } diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h index 7d9b3e44fa..9e2a81b16d 100644 --- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h +++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h @@ -47,7 +47,7 @@ public: int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override; int32_t getMetaState() override; - std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() override; + std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() const override; void updateLedState(bool reset) override; private: @@ -96,8 +96,8 @@ private: void configureParameters(); void dumpParameters(std::string& dump) const; - ui::Rotation getOrientation(); - ui::LogicalDisplayId getDisplayId(); + ui::Rotation getOrientation() const; + ui::LogicalDisplayId getDisplayId() const; [[nodiscard]] std::list<NotifyArgs> processKey(nsecs_t when, nsecs_t readTime, bool down, int32_t scanCode, int32_t usageCode); diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp index fd8224a608..4d08f1965e 100644 --- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp @@ -79,19 +79,17 @@ void MultiTouchInputMapper::syncTouch(nsecs_t when, RawState* outState) { if (id) { outState->rawPointerData.canceledIdBits.markBit(id.value()); } - if (DEBUG_POINTERS) { - ALOGI("Stop processing slot %zu for it received a palm event from device %s", - inIndex, getDeviceName().c_str()); - } + ALOGI_IF(DEBUG_POINTERS, + "Stop processing slot %zu for it received a palm event from device %s", + inIndex, getDeviceName().c_str()); continue; } if (outCount >= MAX_POINTERS) { - if (DEBUG_POINTERS) { - ALOGD("MultiTouch device %s emitted more than maximum of %zu pointers; " - "ignoring the rest.", - getDeviceName().c_str(), MAX_POINTERS); - } + ALOGD_IF(DEBUG_POINTERS, + "MultiTouch device %s emitted more than maximum of %zu pointers; ignoring the " + "rest.", + getDeviceName().c_str(), MAX_POINTERS); break; // too many fingers! } diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.cpp b/services/inputflinger/reader/mapper/SensorInputMapper.cpp index 1f6600d3f6..0d1d8844c1 100644 --- a/services/inputflinger/reader/mapper/SensorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/SensorInputMapper.cpp @@ -235,9 +235,8 @@ void SensorInputMapper::processHardWareTimestamp(nsecs_t evTime, int32_t mscTime // else calculate difference between previous and current MSC_TIMESTAMP if (mPrevMscTime == 0) { mHardwareTimestamp = evTime; - if (DEBUG_SENSOR_EVENT_DETAILS) { - ALOGD("Initialize hardware timestamp = %" PRId64, mHardwareTimestamp); - } + ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS, "Initialize hardware timestamp = %" PRId64, + mHardwareTimestamp); } else { // Calculate the difference between current msc_timestamp and // previous msc_timestamp, including when msc_timestamp wraps around. @@ -330,11 +329,10 @@ void SensorInputMapper::flushSensor(InputDeviceSensorType sensorType) { bool SensorInputMapper::enableSensor(InputDeviceSensorType sensorType, std::chrono::microseconds samplingPeriod, std::chrono::microseconds maxBatchReportLatency) { - if (DEBUG_SENSOR_EVENT_DETAILS) { - ALOGD("Enable Sensor %s samplingPeriod %lld maxBatchReportLatency %lld", - ftl::enum_string(sensorType).c_str(), samplingPeriod.count(), - maxBatchReportLatency.count()); - } + ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS, + "Enable Sensor %s samplingPeriod %lld maxBatchReportLatency %lld", + ftl::enum_string(sensorType).c_str(), samplingPeriod.count(), + maxBatchReportLatency.count()); if (!setSensorEnabled(sensorType, /*enabled=*/true)) { return false; @@ -355,9 +353,7 @@ bool SensorInputMapper::enableSensor(InputDeviceSensorType sensorType, } void SensorInputMapper::disableSensor(InputDeviceSensorType sensorType) { - if (DEBUG_SENSOR_EVENT_DETAILS) { - ALOGD("Disable Sensor %s", ftl::enum_string(sensorType).c_str()); - } + ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS, "Disable Sensor %s", ftl::enum_string(sensorType).c_str()); if (!setSensorEnabled(sensorType, /*enabled=*/false)) { return; @@ -389,15 +385,12 @@ std::list<NotifyArgs> SensorInputMapper::sync(nsecs_t when, bool force) { } nsecs_t timestamp = mHasHardwareTimestamp ? mHardwareTimestamp : when; - if (DEBUG_SENSOR_EVENT_DETAILS) { - ALOGD("Sensor %s timestamp %" PRIu64 " values [%f %f %f]", - ftl::enum_string(sensorType).c_str(), timestamp, values[0], values[1], values[2]); - } + ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS, "Sensor %s timestamp %" PRIu64 " values [%f %f %f]", + ftl::enum_string(sensorType).c_str(), timestamp, values[0], values[1], values[2]); if (sensor.lastSampleTimeNs.has_value() && timestamp - sensor.lastSampleTimeNs.value() < sensor.samplingPeriod.count()) { - if (DEBUG_SENSOR_EVENT_DETAILS) { - ALOGD("Sensor %s Skip a sample.", ftl::enum_string(sensorType).c_str()); - } + ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS, "Sensor %s Skip a sample.", + ftl::enum_string(sensorType).c_str()); } else { // Convert to Android unit convertFromLinuxToAndroid(values, sensorType); diff --git a/services/inputflinger/reader/mapper/SlopController.cpp b/services/inputflinger/reader/mapper/SlopController.cpp index 9ec02a6f86..d55df511e1 100644 --- a/services/inputflinger/reader/mapper/SlopController.cpp +++ b/services/inputflinger/reader/mapper/SlopController.cpp @@ -54,13 +54,13 @@ float SlopController::consumeEvent(nsecs_t eventTimeNanos, float value) { mCumulativeValue += value; if (abs(mCumulativeValue) >= mSlopThreshold) { - ALOGD("SlopController: did not drop event with value .%3f", value); + ALOGD("SlopController: did not drop event with value %.3f", value); mHasSlopBeenMet = true; // Return the amount of value that exceeds the slop. return signOf(value) * (abs(mCumulativeValue) - mSlopThreshold); } - ALOGD("SlopController: dropping event with value .%3f", value); + ALOGD("SlopController: dropping event with value %.3f", value); return 0; } diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index 5c90cbb6ce..4d36db8ff7 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -24,12 +24,15 @@ #include <cinttypes> #include <cmath> #include <cstddef> +#include <sstream> +#include <string> #include <tuple> #include <math.h> #include <android-base/stringprintf.h> #include <android/input.h> +#include <com_android_input_flags.h> #include <ftl/enum.h> #include <input/PrintTools.h> #include <input/PropertyMap.h> @@ -47,6 +50,8 @@ namespace android { +namespace input_flags = com::android::input::flags; + // --- Constants --- // Artificial latency on synthetic events created from stylus data without corresponding touch @@ -135,6 +140,40 @@ void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) con *outY = y; } +std::ostream& operator<<(std::ostream& out, const RawPointerData::Pointer& p) { + out << "id=" << p.id << ", x=" << p.x << ", y=" << p.y << ", pressure=" << p.pressure + << ", touchMajor=" << p.touchMajor << ", touchMinor=" << p.touchMinor + << ", toolMajor=" << p.toolMajor << ", toolMinor=" << p.toolMinor + << ", orientation=" << p.orientation << ", tiltX=" << p.tiltX << ", tiltY=" << p.tiltY + << ", distance=" << p.distance << ", toolType=" << ftl::enum_string(p.toolType) + << ", isHovering=" << p.isHovering; + return out; +} + +std::ostream& operator<<(std::ostream& out, const RawPointerData& data) { + out << data.pointerCount << " pointers:\n"; + for (uint32_t i = 0; i < data.pointerCount; i++) { + out << INDENT << "[" << i << "]: " << data.pointers[i] << std::endl; + } + out << "ID bits: hovering = 0x" << std::hex << std::setfill('0') << std::setw(8) + << data.hoveringIdBits.value << ", touching = 0x" << std::setfill('0') << std::setw(8) + << data.touchingIdBits.value << ", canceled = 0x" << std::setfill('0') << std::setw(8) + << data.canceledIdBits.value << std::dec; + return out; +} + +// --- TouchInputMapper::RawState --- + +std::ostream& operator<<(std::ostream& out, const TouchInputMapper::RawState& state) { + out << "When: " << state.when << std::endl; + out << "Read time: " << state.readTime << std::endl; + out << "Button state: 0x" << std::setfill('0') << std::setw(8) << std::hex << state.buttonState + << std::dec << std::endl; + out << "Raw pointer data:" << std::endl; + out << addLinePrefix(streamableToString(state.rawPointerData), INDENT); + return out; +} + // --- TouchInputMapper --- TouchInputMapper::TouchInputMapper(InputDeviceContext& deviceContext, @@ -229,20 +268,8 @@ void TouchInputMapper::dump(std::string& dump) { dump += StringPrintf(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale); dump += StringPrintf(INDENT3 "Last Raw Button State: 0x%08x\n", mLastRawState.buttonState); - dump += StringPrintf(INDENT3 "Last Raw Touch: pointerCount=%d\n", - mLastRawState.rawPointerData.pointerCount); - for (uint32_t i = 0; i < mLastRawState.rawPointerData.pointerCount; i++) { - const RawPointerData::Pointer& pointer = mLastRawState.rawPointerData.pointers[i]; - dump += StringPrintf(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, " - "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, " - "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, " - "toolType=%s, isHovering=%s\n", - i, pointer.id, pointer.x, pointer.y, pointer.pressure, - pointer.touchMajor, pointer.touchMinor, pointer.toolMajor, - pointer.toolMinor, pointer.orientation, pointer.tiltX, pointer.tiltY, - pointer.distance, ftl::enum_string(pointer.toolType).c_str(), - toString(pointer.isHovering)); - } + dump += INDENT3 "Last Raw Touch:\n"; + dump += addLinePrefix(streamableToString(mLastRawState), INDENT4) + "\n"; dump += StringPrintf(INDENT3 "Last Cooked Button State: 0x%08x\n", mLastCookedState.buttonState); @@ -299,6 +326,8 @@ std::list<NotifyArgs> TouchInputMapper::reconfigure(nsecs_t when, ConfigurationChanges changes) { std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes); + std::optional<ui::LogicalDisplayId> previousDisplayId = getAssociatedDisplayId(); + mConfig = config; // Full configuration should happen the first time configure is called and @@ -347,6 +376,8 @@ std::list<NotifyArgs> TouchInputMapper::reconfigure(nsecs_t when, } if (changes.any() && resetNeeded) { + // Touches should be aborted using the previous display id, so that the stream is consistent + out += abortTouches(when, when, /*policyFlags=*/0, previousDisplayId); out += reset(when); // Send reset, unless this is the first time the device has been configured, @@ -1469,6 +1500,22 @@ std::list<NotifyArgs> TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) { last.rawPointerData.touchingIdBits.value, next.rawPointerData.touchingIdBits.value, last.rawPointerData.hoveringIdBits.value, next.rawPointerData.hoveringIdBits.value, next.rawPointerData.canceledIdBits.value); + if (debugRawEvents() && last.rawPointerData.pointerCount == 0 && + next.rawPointerData.pointerCount == 1) { + // Dump a bunch of info to try to debug b/396796958. + // TODO(b/396796958): remove this debug dump. + ALOGD("pointerCount went from 0 to 1. last:\n%s", + addLinePrefix(streamableToString(last), INDENT).c_str()); + ALOGD("next:\n%s", addLinePrefix(streamableToString(next), INDENT).c_str()); + ALOGD("InputReader dump:"); + // The dump is too long to simply add as a format parameter in one log message, so we have + // to split it by line and log them individually. + std::istringstream stream(mDeviceContext.getContext()->dump()); + std::string line; + while (std::getline(stream, line, '\n')) { + ALOGD(INDENT "%s", line.c_str()); + } + } if (!next.rawPointerData.touchingIdBits.isEmpty() && !next.rawPointerData.hoveringIdBits.isEmpty() && @@ -1575,7 +1622,8 @@ std::list<NotifyArgs> TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t re mLastCookedState.buttonState, mCurrentCookedState.buttonState); // Dispatch the touches either directly or by translation through a pointer on screen. - if (mDeviceMode == DeviceMode::POINTER) { + if (!input_flags::disable_touch_input_mapper_pointer_usage() && + mDeviceMode == DeviceMode::POINTER) { for (BitSet32 idBits(mCurrentRawState.rawPointerData.touchingIdBits); !idBits.isEmpty();) { uint32_t id = idBits.clearFirstMarkedBit(); const RawPointerData::Pointer& pointer = @@ -1613,7 +1661,9 @@ std::list<NotifyArgs> TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t re } out += dispatchPointerUsage(when, readTime, policyFlags, pointerUsage); - } else { + } + if (input_flags::disable_touch_input_mapper_pointer_usage() || + mDeviceMode != DeviceMode::POINTER) { if (!mCurrentMotionAborted) { out += dispatchButtonRelease(when, readTime, policyFlags); out += dispatchHoverExit(when, readTime, policyFlags); @@ -1651,6 +1701,10 @@ bool TouchInputMapper::isTouchScreen() { mParameters.hasAssociatedDisplay; } +ui::LogicalDisplayId TouchInputMapper::resolveDisplayId() const { + return getAssociatedDisplayId().value_or(ui::LogicalDisplayId::INVALID); +}; + void TouchInputMapper::applyExternalStylusButtonState(nsecs_t when) { if (mDeviceMode == DeviceMode::DIRECT && hasExternalStylus()) { // If any of the external buttons are already pressed by the touch device, ignore them. @@ -1922,8 +1976,9 @@ NotifyKeyArgs TouchInputMapper::dispatchVirtualKey(nsecs_t when, nsecs_t readTim keyEventFlags, keyCode, scanCode, metaState, downTime); } -std::list<NotifyArgs> TouchInputMapper::abortTouches(nsecs_t when, nsecs_t readTime, - uint32_t policyFlags) { +std::list<NotifyArgs> TouchInputMapper::abortTouches( + nsecs_t when, nsecs_t readTime, uint32_t policyFlags, + std::optional<ui::LogicalDisplayId> currentGestureDisplayId) { std::list<NotifyArgs> out; if (mCurrentMotionAborted) { // Current motion event was already aborted. @@ -1934,6 +1989,7 @@ std::list<NotifyArgs> TouchInputMapper::abortTouches(nsecs_t when, nsecs_t readT int32_t metaState = getContext()->getGlobalMetaState(); int32_t buttonState = mCurrentCookedState.buttonState; out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + currentGestureDisplayId.value_or(resolveDisplayId()), AMOTION_EVENT_ACTION_CANCEL, 0, AMOTION_EVENT_FLAG_CANCELED, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, mCurrentCookedState.cookedPointerData.pointerProperties, @@ -1988,14 +2044,15 @@ std::list<NotifyArgs> TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t re if (!currentIdBits.isEmpty()) { // No pointer id changes so this is a move event. // The listener takes care of batching moves so we don't have to deal with that here. - out.push_back( - dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, - 0, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, - mCurrentCookedState.cookedPointerData.pointerProperties, - mCurrentCookedState.cookedPointerData.pointerCoords, - mCurrentCookedState.cookedPointerData.idToIndex, currentIdBits, - -1, mOrientedXPrecision, mOrientedYPrecision, mDownTime, - MotionClassification::NONE)); + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), + AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState, + AMOTION_EVENT_EDGE_FLAG_NONE, + mCurrentCookedState.cookedPointerData.pointerProperties, + mCurrentCookedState.cookedPointerData.pointerCoords, + mCurrentCookedState.cookedPointerData.idToIndex, + currentIdBits, -1, mOrientedXPrecision, + mOrientedYPrecision, mDownTime, + MotionClassification::NONE)); } } else { // There may be pointers going up and pointers going down and pointers moving @@ -2025,7 +2082,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t re if (isCanceled) { ALOGI("Canceling pointer %d for the palm event was detected.", upId); } - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_POINTER_UP, 0, isCanceled ? AMOTION_EVENT_FLAG_CANCELED : 0, metaState, buttonState, 0, @@ -2044,7 +2101,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t re // events, they do not generally handle them except when presented in a move event. if (moveNeeded && !moveIdBits.isEmpty()) { ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value); - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState, 0, mCurrentCookedState.cookedPointerData.pointerProperties, mCurrentCookedState.cookedPointerData.pointerCoords, @@ -2065,7 +2122,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t re } out.push_back( - dispatchMotion(when, readTime, policyFlags, mSource, + dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_POINTER_DOWN, 0, 0, metaState, buttonState, 0, mCurrentCookedState.cookedPointerData.pointerProperties, mCurrentCookedState.cookedPointerData.pointerCoords, @@ -2084,7 +2141,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchHoverExit(nsecs_t when, nsecs_t (mCurrentCookedState.cookedPointerData.hoveringIdBits.isEmpty() || !mCurrentCookedState.cookedPointerData.touchingIdBits.isEmpty())) { int32_t metaState = getContext()->getGlobalMetaState(); - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastCookedState.buttonState, 0, mLastCookedState.cookedPointerData.pointerProperties, @@ -2105,7 +2162,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, !mCurrentCookedState.cookedPointerData.hoveringIdBits.isEmpty()) { int32_t metaState = getContext()->getGlobalMetaState(); if (!mSentHoverEnter) { - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0, metaState, mCurrentRawState.buttonState, 0, mCurrentCookedState.cookedPointerData.pointerProperties, @@ -2117,7 +2174,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, mSentHoverEnter = true; } - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState, mCurrentRawState.buttonState, 0, mCurrentCookedState.cookedPointerData.pointerProperties, @@ -2140,7 +2197,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchButtonRelease(nsecs_t when, nsec while (!releasedButtons.isEmpty()) { int32_t actionButton = BitSet32::valueForBit(releasedButtons.clearFirstMarkedBit()); buttonState &= ~actionButton; - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0, metaState, buttonState, 0, mLastCookedState.cookedPointerData.pointerProperties, @@ -2162,7 +2219,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchButtonPress(nsecs_t when, nsecs_ while (!pressedButtons.isEmpty()) { int32_t actionButton = BitSet32::valueForBit(pressedButtons.clearFirstMarkedBit()); buttonState |= actionButton; - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0, metaState, buttonState, 0, mCurrentCookedState.cookedPointerData.pointerProperties, @@ -2186,7 +2243,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchGestureButtonRelease(nsecs_t whe while (!releasedButtons.isEmpty()) { int32_t actionButton = BitSet32::valueForBit(releasedButtons.clearFirstMarkedBit()); buttonState &= ~actionButton; - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0, metaState, buttonState, 0, mPointerGesture.lastGestureProperties, @@ -2210,7 +2267,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchGestureButtonPress(nsecs_t when, while (!pressedButtons.isEmpty()) { int32_t actionButton = BitSet32::valueForBit(pressedButtons.clearFirstMarkedBit()); buttonState |= actionButton; - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0, metaState, buttonState, 0, mPointerGesture.currentGestureProperties, mPointerGesture.currentGestureCoords, @@ -2251,6 +2308,23 @@ void TouchInputMapper::cookPointerData() { for (uint32_t i = 0; i < currentPointerCount; i++) { const RawPointerData::Pointer& in = mCurrentRawState.rawPointerData.pointers[i]; + bool isHovering = in.isHovering; + + // A tool MOUSE pointer is only down/touching when a mouse button is pressed. + if (input_flags::disable_touch_input_mapper_pointer_usage() && + in.toolType == ToolType::MOUSE && + !mCurrentRawState.rawPointerData.canceledIdBits.hasBit(in.id)) { + if (isPointerDown(mCurrentRawState.buttonState)) { + isHovering = false; + mCurrentCookedState.cookedPointerData.touchingIdBits.markBit(in.id); + mCurrentCookedState.cookedPointerData.hoveringIdBits.clearBit(in.id); + } else { + isHovering = true; + mCurrentCookedState.cookedPointerData.touchingIdBits.clearBit(in.id); + mCurrentCookedState.cookedPointerData.hoveringIdBits.markBit(in.id); + } + } + // Size float touchMajor, touchMinor, toolMajor, toolMinor, size; switch (mCalibration.sizeCalibration) { @@ -2340,7 +2414,7 @@ void TouchInputMapper::cookPointerData() { pressure = in.pressure * mPressureScale; break; default: - pressure = in.isHovering ? 0 : 1; + pressure = isHovering ? 0 : 1; break; } @@ -2541,7 +2615,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns if (!dispatchedGestureIdBits.isEmpty()) { if (cancelPreviousGesture) { const uint32_t cancelFlags = flags | AMOTION_EVENT_FLAG_CANCELED; - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_CANCEL, 0, cancelFlags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.lastGestureProperties, @@ -2568,8 +2642,9 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns } const uint32_t id = upGestureIdBits.clearFirstMarkedBit(); out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, - AMOTION_EVENT_ACTION_POINTER_UP, 0, flags, metaState, - buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, + resolveDisplayId(), AMOTION_EVENT_ACTION_POINTER_UP, 0, + flags, metaState, buttonState, + AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.lastGestureProperties, mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, @@ -2583,13 +2658,14 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns // Send motion events for all pointers that moved. if (moveNeeded) { - out.push_back( - dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, - flags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, - mPointerGesture.currentGestureProperties, - mPointerGesture.currentGestureCoords, - mPointerGesture.currentGestureIdToIndex, dispatchedGestureIdBits, -1, - 0, 0, mPointerGesture.downTime, classification)); + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), + AMOTION_EVENT_ACTION_MOVE, 0, flags, metaState, buttonState, + AMOTION_EVENT_EDGE_FLAG_NONE, + mPointerGesture.currentGestureProperties, + mPointerGesture.currentGestureCoords, + mPointerGesture.currentGestureIdToIndex, + dispatchedGestureIdBits, -1, 0, 0, mPointerGesture.downTime, + classification)); } // Send motion events for all pointers that went down. @@ -2604,7 +2680,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns mPointerGesture.downTime = when; } - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_POINTER_DOWN, 0, flags, metaState, buttonState, 0, mPointerGesture.currentGestureProperties, mPointerGesture.currentGestureCoords, @@ -2622,7 +2698,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns // Send motion events for hover. if (mPointerGesture.currentGestureMode == PointerGesture::Mode::HOVER) { - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_HOVER_MOVE, 0, flags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.currentGestureProperties, @@ -2681,7 +2757,7 @@ std::list<NotifyArgs> TouchInputMapper::abortPointerGestures(nsecs_t when, nsecs if (!mPointerGesture.lastGestureIdBits.isEmpty()) { int32_t metaState = getContext()->getGlobalMetaState(); int32_t buttonState = mCurrentRawState.buttonState; - out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, + out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, resolveDisplayId(), AMOTION_EVENT_ACTION_CANCEL, 0, AMOTION_EVENT_FLAG_CANCELED, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.lastGestureProperties, @@ -3475,8 +3551,7 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerMouse(nsecs_t when, nsecs hovering = false; } - return dispatchPointerSimple(when, readTime, policyFlags, down, hovering, - ui::LogicalDisplayId::INVALID); + return dispatchPointerSimple(when, readTime, policyFlags, down, hovering, resolveDisplayId()); } std::list<NotifyArgs> TouchInputMapper::abortPointerMouse(nsecs_t when, nsecs_t readTime, @@ -3639,11 +3714,12 @@ std::list<NotifyArgs> TouchInputMapper::abortPointerSimple(nsecs_t when, nsecs_t } NotifyMotionArgs TouchInputMapper::dispatchMotion( - nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action, - int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState, - int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords, + nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, + ui::LogicalDisplayId displayId, int32_t action, int32_t actionButton, int32_t flags, + int32_t metaState, int32_t buttonState, int32_t edgeFlags, + const PropertiesArray& properties, const CoordsArray& coords, const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision, - float yPrecision, nsecs_t downTime, MotionClassification classification) { + float yPrecision, nsecs_t downTime, MotionClassification classification) const { std::vector<PointerCoords> pointerCoords; std::vector<PointerProperties> pointerProperties; uint32_t pointerCount = 0; @@ -3691,13 +3767,13 @@ NotifyMotionArgs TouchInputMapper::dispatchMotion( } } - const ui::LogicalDisplayId displayId = - getAssociatedDisplayId().value_or(ui::LogicalDisplayId::INVALID); - float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION; float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION; if (mDeviceMode == DeviceMode::POINTER) { - xCursorPosition = yCursorPosition = 0.f; + ALOGW_IF(pointerCount != 1, + "Only single pointer events are fully supported in POINTER mode"); + xCursorPosition = pointerCoords[0].getX(); + yCursorPosition = pointerCoords[0].getY(); } const DeviceId deviceId = getDeviceId(); std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames(); @@ -3713,7 +3789,7 @@ NotifyMotionArgs TouchInputMapper::dispatchMotion( std::list<NotifyArgs> TouchInputMapper::cancelTouch(nsecs_t when, nsecs_t readTime) { std::list<NotifyArgs> out; out += abortPointerUsage(when, readTime, /*policyFlags=*/0); - out += abortTouches(when, readTime, /* policyFlags=*/0); + out += abortTouches(when, readTime, /* policyFlags=*/0, std::nullopt); return out; } @@ -3966,15 +4042,9 @@ bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, return true; } -std::optional<ui::LogicalDisplayId> TouchInputMapper::getAssociatedDisplayId() { - if (mParameters.hasAssociatedDisplay) { - if (mDeviceMode == DeviceMode::POINTER) { - return ui::LogicalDisplayId::INVALID; - } else { - return std::make_optional(mViewport.displayId); - } - } - return std::nullopt; +std::optional<ui::LogicalDisplayId> TouchInputMapper::getAssociatedDisplayId() const { + return mParameters.hasAssociatedDisplay ? std::make_optional(mViewport.displayId) + : std::nullopt; } } // namespace android diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h index ef0e02f40c..45fc6bfa36 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -185,7 +185,7 @@ public: [[nodiscard]] std::list<NotifyArgs> timeoutExpired(nsecs_t when) override; [[nodiscard]] std::list<NotifyArgs> updateExternalStylusState( const StylusState& state) override; - std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() override; + std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() const override; protected: CursorButtonAccumulator mCursorButtonAccumulator; @@ -215,7 +215,7 @@ protected: DISABLED, // input is disabled DIRECT, // direct mapping (touchscreen) NAVIGATION, // unscaled mapping with assist gesture (touch navigation) - POINTER, // pointer mapping (e.g. uncaptured touchpad, drawing tablet) + POINTER, // pointer mapping (e.g. absolute mouse, drawing tablet) ftl_last = POINTER }; @@ -234,8 +234,11 @@ protected: ftl_last = POINTER }; + // TouchInputMapper will configure devices with INPUT_PROP_DIRECT as + // DeviceType::TOUCH_SCREEN, and will otherwise use DeviceType::POINTER by default. + // This can be overridden by IDC files, using the `touch.deviceType` config. DeviceType deviceType; - bool hasAssociatedDisplay; + bool hasAssociatedDisplay = false; bool associatedDisplayIsExternal; bool orientationAware; @@ -345,6 +348,8 @@ protected: inline void clear() { *this = RawState(); } }; + friend std::ostream& operator<<(std::ostream& out, const RawState& state); + struct CookedState { // Cooked pointer sample data. CookedPointerData cookedPointerData{}; @@ -776,8 +781,9 @@ private: nsecs_t readTime); const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData); void cookPointerData(); - [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime, - uint32_t policyFlags); + [[nodiscard]] std::list<NotifyArgs> abortTouches( + nsecs_t when, nsecs_t readTime, uint32_t policyFlags, + std::optional<ui::LogicalDisplayId> gestureDisplayId); [[nodiscard]] std::list<NotifyArgs> dispatchPointerUsage(nsecs_t when, nsecs_t readTime, uint32_t policyFlags, @@ -833,15 +839,18 @@ private: // method will take care of setting the index and transmuting the action to DOWN or UP // it is the first / last pointer to go down / up. [[nodiscard]] NotifyMotionArgs dispatchMotion( - nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action, - int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState, - int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords, + nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, + ui::LogicalDisplayId displayId, int32_t action, int32_t actionButton, int32_t flags, + int32_t metaState, int32_t buttonState, int32_t edgeFlags, + const PropertiesArray& properties, const CoordsArray& coords, const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision, - float yPrecision, nsecs_t downTime, MotionClassification classification); + float yPrecision, nsecs_t downTime, MotionClassification classification) const; // Returns if this touch device is a touch screen with an associated display. bool isTouchScreen(); + ui::LogicalDisplayId resolveDisplayId() const; + bool isPointInsidePhysicalFrame(int32_t x, int32_t y) const; const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y); diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp index 0c094e6cce..c982dab019 100644 --- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp @@ -40,6 +40,7 @@ #include "TouchCursorInputMapperCommon.h" #include "TouchpadInputMapper.h" #include "gestures/HardwareProperties.h" +#include "gestures/Logging.h" #include "gestures/TimerProvider.h" #include "ui/Rotation.h" @@ -49,19 +50,12 @@ namespace android { namespace { -/** - * Log details of each gesture output by the gestures library. - * Enable this via "adb shell setprop log.tag.TouchpadInputMapperGestures DEBUG" (requires - * restarting the shell) - */ -const bool DEBUG_TOUCHPAD_GESTURES = - __android_log_is_loggable(ANDROID_LOG_DEBUG, "TouchpadInputMapperGestures", - ANDROID_LOG_INFO); - std::vector<double> createAccelerationCurveForSensitivity(int32_t sensitivity, + bool accelerationEnabled, size_t propertySize) { - std::vector<AccelerationCurveSegment> segments = - createAccelerationCurveForPointerSensitivity(sensitivity); + std::vector<AccelerationCurveSegment> segments = accelerationEnabled + ? createAccelerationCurveForPointerSensitivity(sensitivity) + : createFlatAccelerationCurve(sensitivity); LOG_ALWAYS_FATAL_IF(propertySize < 4 * segments.size()); std::vector<double> output(propertySize, 0); @@ -358,12 +352,14 @@ std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when, GesturesProp accelCurveProp = mPropertyProvider.getProperty("Pointer Accel Curve"); accelCurveProp.setRealValues( createAccelerationCurveForSensitivity(config.touchpadPointerSpeed, + config.touchpadAccelerationEnabled, accelCurveProp.getCount())); mPropertyProvider.getProperty("Use Custom Touchpad Scroll Accel Curve") .setBoolValues({true}); GesturesProp scrollCurveProp = mPropertyProvider.getProperty("Scroll Accel Curve"); scrollCurveProp.setRealValues( createAccelerationCurveForSensitivity(config.touchpadPointerSpeed, + config.touchpadAccelerationEnabled, scrollCurveProp.getCount())); mPropertyProvider.getProperty("Scroll X Out Scale").setRealValues({1.0}); mPropertyProvider.getProperty("Scroll Y Out Scale").setRealValues({1.0}); @@ -466,7 +462,7 @@ void TouchpadInputMapper::updatePalmDetectionMetrics() { std::list<NotifyArgs> TouchpadInputMapper::sendHardwareState(nsecs_t when, nsecs_t readTime, SelfContainedHardwareState schs) { - ALOGD_IF(DEBUG_TOUCHPAD_GESTURES, "New hardware state: %s", schs.state.String().c_str()); + ALOGD_IF(debugTouchpadGestures(), "New hardware state: %s", schs.state.String().c_str()); mGestureInterpreter->PushHardwareState(&schs.state); return processGestures(when, readTime); } @@ -477,7 +473,7 @@ std::list<NotifyArgs> TouchpadInputMapper::timeoutExpired(nsecs_t when) { } void TouchpadInputMapper::consumeGesture(const Gesture* gesture) { - ALOGD_IF(DEBUG_TOUCHPAD_GESTURES, "Gesture ready: %s", gesture->String().c_str()); + ALOGD_IF(debugTouchpadGestures(), "Gesture ready: %s", gesture->String().c_str()); if (mResettingInterpreter) { // We already handle tidying up fake fingers etc. in GestureConverter::reset, so we should // ignore any gestures produced from the interpreter while we're resetting it. @@ -502,7 +498,7 @@ std::list<NotifyArgs> TouchpadInputMapper::processGestures(nsecs_t when, nsecs_t return out; } -std::optional<ui::LogicalDisplayId> TouchpadInputMapper::getAssociatedDisplayId() { +std::optional<ui::LogicalDisplayId> TouchpadInputMapper::getAssociatedDisplayId() const { return mDisplayId; } @@ -510,4 +506,12 @@ std::optional<HardwareProperties> TouchpadInputMapper::getTouchpadHardwareProper return mHardwareProperties; } +std::optional<GesturesProp> TouchpadInputMapper::getGesturePropertyForTesting( + const std::string& name) { + if (!mPropertyProvider.hasProperty(name)) { + return std::nullopt; + } + return mPropertyProvider.getProperty(name); +} + } // namespace android diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.h b/services/inputflinger/reader/mapper/TouchpadInputMapper.h index a2c4be9e50..9f53a7ba85 100644 --- a/services/inputflinger/reader/mapper/TouchpadInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.h @@ -66,10 +66,12 @@ public: using MetricsIdentifier = std::tuple<uint16_t /*busId*/, uint16_t /*vendorId*/, uint16_t /*productId*/, uint16_t /*version*/>; - std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() override; + std::optional<ui::LogicalDisplayId> getAssociatedDisplayId() const override; std::optional<HardwareProperties> getTouchpadHardwareProperties() override; + std::optional<GesturesProp> getGesturePropertyForTesting(const std::string& name); + private: void resetGestureInterpreter(nsecs_t when); explicit TouchpadInputMapper(InputDeviceContext& deviceContext, diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp index a3a48ef034..264ef6f3e0 100644 --- a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp @@ -43,10 +43,8 @@ std::list<NotifyArgs> VibratorInputMapper::process(const RawEvent& rawEvent) { std::list<NotifyArgs> VibratorInputMapper::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) { - if (DEBUG_VIBRATOR) { - ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%zd, token=%d", getDeviceId(), - sequence.toString().c_str(), repeat, token); - } + ALOGD_IF(DEBUG_VIBRATOR, "vibrate: deviceId=%d, pattern=[%s], repeat=%zd, token=%d", + getDeviceId(), sequence.toString().c_str(), repeat, token); std::list<NotifyArgs> out; mVibrating = true; @@ -63,9 +61,7 @@ std::list<NotifyArgs> VibratorInputMapper::vibrate(const VibrationSequence& sequ } std::list<NotifyArgs> VibratorInputMapper::cancelVibrate(int32_t token) { - if (DEBUG_VIBRATOR) { - ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token); - } + ALOGD_IF(DEBUG_VIBRATOR, "cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token); std::list<NotifyArgs> out; if (mVibrating && mToken == token) { @@ -95,9 +91,7 @@ std::list<NotifyArgs> VibratorInputMapper::timeoutExpired(nsecs_t when) { } std::list<NotifyArgs> VibratorInputMapper::nextStep() { - if (DEBUG_VIBRATOR) { - ALOGD("nextStep: index=%d, vibrate deviceId=%d", (int)mIndex, getDeviceId()); - } + ALOGD_IF(DEBUG_VIBRATOR, "nextStep: index=%d, vibrate deviceId=%d", (int)mIndex, getDeviceId()); std::list<NotifyArgs> out; mIndex += 1; if (size_t(mIndex) >= mSequence.pattern.size()) { @@ -111,16 +105,11 @@ std::list<NotifyArgs> VibratorInputMapper::nextStep() { const VibrationElement& element = mSequence.pattern[mIndex]; if (element.isOn()) { - if (DEBUG_VIBRATOR) { - std::string description = element.toString(); - ALOGD("nextStep: sending vibrate deviceId=%d, element=%s", getDeviceId(), - description.c_str()); - } + ALOGD_IF(DEBUG_VIBRATOR, "nextStep: sending vibrate deviceId=%d, element=%s", getDeviceId(), + element.toString().c_str()); getDeviceContext().vibrate(element); } else { - if (DEBUG_VIBRATOR) { - ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId()); - } + ALOGD_IF(DEBUG_VIBRATOR, "nextStep: sending cancel vibrate deviceId=%d", getDeviceId()); getDeviceContext().cancelVibrate(); } nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); @@ -128,17 +117,13 @@ std::list<NotifyArgs> VibratorInputMapper::nextStep() { std::chrono::duration_cast<std::chrono::nanoseconds>(element.duration); mNextStepTime = now + duration.count(); getContext()->requestTimeoutAtTime(mNextStepTime); - if (DEBUG_VIBRATOR) { - ALOGD("nextStep: scheduled timeout in %lldms", element.duration.count()); - } + ALOGD_IF(DEBUG_VIBRATOR, "nextStep: scheduled timeout in %lldms", element.duration.count()); return out; } NotifyVibratorStateArgs VibratorInputMapper::stopVibrating() { mVibrating = false; - if (DEBUG_VIBRATOR) { - ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId()); - } + ALOGD_IF(DEBUG_VIBRATOR, "stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId()); getDeviceContext().cancelVibrate(); // Request InputReader to notify InputManagerService for vibration complete. diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp index 827076a2cf..3255877cf1 100644 --- a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp +++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp @@ -14,11 +14,15 @@ * limitations under the License. */ +#include "../Macros.h" + #include "gestures/GestureConverter.h" +#include <ios> #include <optional> #include <sstream> +#include <android-base/logging.h> #include <android-base/stringprintf.h> #include <com_android_input_flags.h> #include <ftl/enum.h> @@ -35,9 +39,6 @@ namespace android { namespace { -// This will disable the tap to click while the user is typing on a physical keyboard -const bool ENABLE_TOUCHPAD_PALM_REJECTION = input_flags::enable_touchpad_typing_palm_rejection(); - // In addition to v1, v2 will also cancel ongoing move gestures while typing and add delay in // re-enabling the tap to click. const bool ENABLE_TOUCHPAD_PALM_REJECTION_V2 = @@ -222,8 +223,7 @@ std::list<NotifyArgs> GestureConverter::handleMove(nsecs_t when, nsecs_t readTim if (!mIsHoverCancelled) { // handleFling calls hoverMove with zero delta on FLING_TAP_DOWN. Don't enable tap to click // for this case as subsequent handleButtonsChange may choose to ignore this tap. - if ((ENABLE_TOUCHPAD_PALM_REJECTION || ENABLE_TOUCHPAD_PALM_REJECTION_V2) && - (std::abs(deltaX) > 0 || std::abs(deltaY) > 0)) { + if (std::abs(deltaX) > 0 || std::abs(deltaY) > 0) { enableTapToClick(when); } } @@ -250,6 +250,18 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_ const Gesture& gesture) { std::list<NotifyArgs> out = {}; + if (mCurrentClassification != MotionClassification::NONE) { + // Handling button changes during an ongoing gesture would be tricky, as we'd have to avoid + // sending duplicate DOWN events or premature UP events (e.g. if the gesture ended but the + // button was still down). It would also make handling touchpad events more difficult for + // apps, which would have to handle cases where e.g. a scroll gesture ends (and therefore + // the event lose the TWO_FINGER_SWIPE classification) but there isn't an UP because the + // button's still down. It's unclear how one should even handle button changes during most + // gestures, and they're probably accidental anyway. So, instead, just ignore them. + LOG(INFO) << "Ignoring button change because a gesture is ongoing."; + return out; + } + PointerCoords coords; coords.clear(); coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0); @@ -262,7 +274,7 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_ // return early to prevent this tap return out; } - } else if (ENABLE_TOUCHPAD_PALM_REJECTION && mReaderContext.isPreventingTouchpadTaps()) { + } else if (mReaderContext.isPreventingTouchpadTaps()) { enableTapToClick(when); if (gesture.details.buttons.is_tap) { // return early to prevent this tap @@ -312,6 +324,15 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_ for (uint32_t button = 1; button <= GESTURES_BUTTON_FORWARD; button <<= 1) { if (buttonsReleased & button) { uint32_t actionButton = gesturesButtonToMotionEventButton(button); + if (!(newButtonState & actionButton)) { + // We must have received the ButtonsChange gesture that put this button down during + // another gesture, and therefore dropped the BUTTON_PRESS action for it, or + // released the button when another gesture began during its press. Drop the + // BUTTON_RELEASE too to keep the stream consistent. + LOG(INFO) << "Dropping release event for button 0x" << std::hex << actionButton + << " as it wasn't in the button state."; + continue; + } newButtonState &= ~actionButton; out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, newButtonState, /* pointerCount= */ 1, @@ -362,7 +383,7 @@ std::list<NotifyArgs> GestureConverter::handleScroll(nsecs_t when, nsecs_t readT std::list<NotifyArgs> out; PointerCoords& coords = mFakeFingerCoords[0]; if (mCurrentClassification != MotionClassification::TWO_FINGER_SWIPE) { - out += exitHover(when, readTime); + out += prepareForFakeFingerGesture(when, readTime); mCurrentClassification = MotionClassification::TWO_FINGER_SWIPE; coords.clear(); @@ -421,7 +442,7 @@ std::list<NotifyArgs> GestureConverter::handleFling(nsecs_t when, nsecs_t readTi std::list<NotifyArgs> out; mDownTime = when; mCurrentClassification = MotionClassification::TWO_FINGER_SWIPE; - out += exitHover(when, readTime); + out += prepareForFakeFingerGesture(when, readTime); out.push_back(makeMotionArgs(when, readTime, AMOTION_EVENT_ACTION_DOWN, /*actionButton=*/0, /*buttonState=*/0, /*pointerCount=*/1, &coords)); @@ -479,7 +500,7 @@ std::list<NotifyArgs> GestureConverter::endScroll(nsecs_t when, nsecs_t readTime // separate swipes with an appropriate lift event between them, so we don't have to worry // about the finger count changing mid-swipe. - out += exitHover(when, readTime); + out += prepareForFakeFingerGesture(when, readTime); mCurrentClassification = MotionClassification::MULTI_FINGER_SWIPE; @@ -567,9 +588,7 @@ std::list<NotifyArgs> GestureConverter::endScroll(nsecs_t when, nsecs_t readTime LOG_ALWAYS_FATAL_IF(gesture.details.pinch.zoom_state != GESTURES_ZOOM_START, "First pinch gesture does not have the START zoom state (%d instead).", gesture.details.pinch.zoom_state); - std::list<NotifyArgs> out; - - out += exitHover(when, readTime); + std::list<NotifyArgs> out = prepareForFakeFingerGesture(when, readTime); mCurrentClassification = MotionClassification::PINCH; mPinchFingerSeparation = INITIAL_PINCH_SEPARATION_PX; @@ -644,6 +663,16 @@ std::list<NotifyArgs> GestureConverter::exitHover(nsecs_t when, nsecs_t readTime } } +std::list<NotifyArgs> GestureConverter::prepareForFakeFingerGesture(nsecs_t when, + nsecs_t readTime) { + std::list<NotifyArgs> out; + if (isPointerDown(mButtonState)) { + out += releaseAllButtons(when, readTime); + } + out += exitHover(when, readTime); + return out; +} + NotifyMotionArgs GestureConverter::makeHoverEvent(nsecs_t when, nsecs_t readTime, int32_t action) { PointerCoords coords; coords.clear(); diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.h b/services/inputflinger/reader/mapper/gestures/GestureConverter.h index be76b61ce6..ae85e3a4ff 100644 --- a/services/inputflinger/reader/mapper/gestures/GestureConverter.h +++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.h @@ -92,6 +92,8 @@ private: [[nodiscard]] std::list<NotifyArgs> enterHover(nsecs_t when, nsecs_t readTime); [[nodiscard]] std::list<NotifyArgs> exitHover(nsecs_t when, nsecs_t readTime); + [[nodiscard]] std::list<NotifyArgs> prepareForFakeFingerGesture(nsecs_t when, nsecs_t readTime); + NotifyMotionArgs makeHoverEvent(nsecs_t when, nsecs_t readTime, int32_t action); NotifyMotionArgs makeMotionArgs(nsecs_t when, nsecs_t readTime, int32_t action, @@ -107,7 +109,7 @@ private: const bool mEnableNoFocusChange; bool mEnableSystemGestures{true}; - bool mThreeFingerTapShortcutEnabled; + bool mThreeFingerTapShortcutEnabled{false}; std::optional<ui::LogicalDisplayId> mDisplayId; FloatRect mBoundsInLogicalDisplay{}; diff --git a/services/inputflinger/reader/mapper/gestures/GesturesLogging.cpp b/services/inputflinger/reader/mapper/gestures/GesturesLogcatAdapter.cpp index 26028c5643..51905f92cf 100644 --- a/services/inputflinger/reader/mapper/gestures/GesturesLogging.cpp +++ b/services/inputflinger/reader/mapper/gestures/GesturesLogcatAdapter.cpp @@ -22,29 +22,17 @@ #include <log/log.h> +#include "Logging.h" #include "include/gestures.h" extern "C" { -namespace { - -/** - * Log details of each gesture output by the gestures library. - * Enable this via "adb shell setprop log.tag.TouchpadInputMapperGestures DEBUG" (requires - * restarting the shell) - */ -const bool DEBUG_TOUCHPAD_GESTURES = - __android_log_is_loggable(ANDROID_LOG_DEBUG, "TouchpadInputMapperGestures", - ANDROID_LOG_INFO); - -} // namespace - void gestures_log(int verb, const char* fmt, ...) { va_list args; va_start(args, fmt); if (verb == GESTURES_LOG_ERROR) { LOG_PRI_VA(ANDROID_LOG_ERROR, LOG_TAG, fmt, args); - } else if (DEBUG_TOUCHPAD_GESTURES) { + } else if (android::debugTouchpadGestures()) { if (verb == GESTURES_LOG_INFO) { LOG_PRI_VA(ANDROID_LOG_INFO, LOG_TAG, fmt, args); } else { diff --git a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp index 6885adb242..3e62f368a4 100644 --- a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp +++ b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp @@ -25,12 +25,8 @@ #include <com_android_input_flags.h> #include <linux/input-event-codes.h> -namespace input_flags = com::android::input::flags; - namespace android { -const bool REPORT_PALMS_TO_GESTURES_LIBRARY = input_flags::report_palms_to_gestures_library(); - HardwareStateConverter::HardwareStateConverter(const InputDeviceContext& deviceContext, MultiTouchMotionAccumulator& motionAccumulator) : mDeviceContext(deviceContext), @@ -81,18 +77,11 @@ SelfContainedHardwareState HardwareStateConverter::produceHardwareState(nsecs_t } schs.fingers.clear(); - size_t numPalms = 0; for (size_t i = 0; i < mMotionAccumulator.getSlotCount(); i++) { MultiTouchMotionAccumulator::Slot slot = mMotionAccumulator.getSlot(i); if (!slot.isInUse()) { continue; } - // Some touchpads continue to report contacts even after they've identified them as palms. - // We want to exclude these contacts from the HardwareStates. - if (!REPORT_PALMS_TO_GESTURES_LIBRARY && slot.getToolType() == ToolType::PALM) { - numPalms++; - continue; - } FingerState& fingerState = schs.fingers.emplace_back(); fingerState = {}; @@ -105,15 +94,13 @@ SelfContainedHardwareState HardwareStateConverter::produceHardwareState(nsecs_t fingerState.position_x = slot.getX(); fingerState.position_y = slot.getY(); fingerState.tracking_id = slot.getTrackingId(); - if (REPORT_PALMS_TO_GESTURES_LIBRARY) { - fingerState.tool_type = slot.getToolType() == ToolType::PALM - ? FingerState::ToolType::kPalm - : FingerState::ToolType::kFinger; - } + fingerState.tool_type = slot.getToolType() == ToolType::PALM + ? FingerState::ToolType::kPalm + : FingerState::ToolType::kFinger; } schs.state.fingers = schs.fingers.data(); schs.state.finger_cnt = schs.fingers.size(); - schs.state.touch_cnt = mTouchButtonAccumulator.getTouchCount() - numPalms; + schs.state.touch_cnt = mTouchButtonAccumulator.getTouchCount(); return schs; } diff --git a/services/inputflinger/reader/mapper/gestures/Logging.cpp b/services/inputflinger/reader/mapper/gestures/Logging.cpp new file mode 100644 index 0000000000..b9b97c330c --- /dev/null +++ b/services/inputflinger/reader/mapper/gestures/Logging.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Logging.h" + +#include <android-base/properties.h> +#include <log/log.h> + +namespace { + +const bool IS_DEBUGGABLE_BUILD = +#if defined(__ANDROID__) + android::base::GetBoolProperty("ro.debuggable", false); +#else + true; +#endif + +} // namespace + +namespace android { + +bool debugTouchpadGestures() { + if (!IS_DEBUGGABLE_BUILD) { + static const bool DEBUG_RAW_EVENTS = + __android_log_is_loggable(ANDROID_LOG_DEBUG, "TouchpadInputMapperGestures", + ANDROID_LOG_INFO); + return DEBUG_RAW_EVENTS; + } + return __android_log_is_loggable(ANDROID_LOG_DEBUG, "TouchpadInputMapperGestures", + ANDROID_LOG_INFO); +} + +} // namespace android
\ No newline at end of file diff --git a/services/inputflinger/reader/mapper/gestures/Logging.h b/services/inputflinger/reader/mapper/gestures/Logging.h new file mode 100644 index 0000000000..db59fb3dca --- /dev/null +++ b/services/inputflinger/reader/mapper/gestures/Logging.h @@ -0,0 +1,29 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +namespace android { + +/** + * Log details of touchpad gesture library input, output, and processing. + * Enable this via "adb shell setprop log.tag.TouchpadInputMapperGestures DEBUG". + * This requires a restart on non-debuggable (e.g. user) builds, but should take effect immediately + * on debuggable builds (e.g. userdebug). + */ +bool debugTouchpadGestures(); + +} // namespace android
\ No newline at end of file diff --git a/services/inputflinger/rust/Android.bp b/services/inputflinger/rust/Android.bp index 5b7cc2d432..78674e5a0c 100644 --- a/services/inputflinger/rust/Android.bp +++ b/services/inputflinger/rust/Android.bp @@ -40,14 +40,14 @@ rust_defaults { crate_name: "inputflinger", srcs: ["lib.rs"], rustlibs: [ - "libcxx", - "com.android.server.inputflinger-rust", "android.hardware.input.common-V1-rust", + "com.android.server.inputflinger-rust", "libbinder_rs", + "libcxx", + "libinput_rust", "liblog_rust", "liblogger", "libnix", - "libinput_rust", ], host_supported: true, } diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp index 600ae526f1..677cf1e6c4 100644 --- a/services/inputflinger/tests/Android.bp +++ b/services/inputflinger/tests/Android.bp @@ -40,17 +40,19 @@ cc_test { // defaults rather than including them as shared or static libraries. By doing so, the tests // will always run against the compiled version of the inputflinger code rather than the // version on the device. + "libinputdispatcher_defaults", "libinputflinger_base_defaults", + "libinputflinger_defaults", "libinputreader_defaults", "libinputreporter_defaults", - "libinputdispatcher_defaults", - "libinputflinger_defaults", ], srcs: [ ":inputdispatcher_common_test_sources", + "AndroidInputEventProtoConverter_test.cpp", "AnrTracker_test.cpp", "CapturedTouchpadEventConverter_test.cpp", "CursorInputMapper_test.cpp", + "DisplayTopologyGraph_test.cpp", "EventHub_test.cpp", "FakeEventHub.cpp", "FakeInputReaderPolicy.cpp", @@ -62,16 +64,18 @@ cc_test { "HardwareStateConverter_test.cpp", "InputDeviceMetricsCollector_test.cpp", "InputDeviceMetricsSource_test.cpp", + "InputDispatcher_test.cpp", "InputMapperTest.cpp", - "InputProcessor_test.cpp", "InputProcessorConverter_test.cpp", - "InputDispatcher_test.cpp", + "InputProcessor_test.cpp", "InputReader_test.cpp", "InputTraceSession.cpp", "InputTracingTest.cpp", "InstrumentedInputReader.cpp", "JoystickInputMapper_test.cpp", + "KeyboardInputMapper_test.cpp", "LatencyTracker_test.cpp", + "MultiTouchInputMapper_test.cpp", "MultiTouchMotionAccumulator_test.cpp", "NotifyArgs_test.cpp", "PointerChoreographer_test.cpp", @@ -82,14 +86,12 @@ cc_test { "SlopController_test.cpp", "SwitchInputMapper_test.cpp", "SyncQueue_test.cpp", - "TimerProvider_test.cpp", "TestInputListener.cpp", + "TimerProvider_test.cpp", "TouchpadInputMapper_test.cpp", - "VibratorInputMapper_test.cpp", - "MultiTouchInputMapper_test.cpp", - "KeyboardInputMapper_test.cpp", "UinputDevice.cpp", "UnwantedInteractionBlocker_test.cpp", + "VibratorInputMapper_test.cpp", ], aidl: { include_dirs: [ @@ -109,7 +111,14 @@ cc_test { undefined: true, all_undefined: true, diag: { + cfi: true, + integer_overflow: true, + memtag_heap: true, undefined: true, + misc_undefined: [ + "all", + "bounds", + ], }, }, static_libs: [ @@ -121,8 +130,8 @@ cc_test { unit_test: true, }, test_suites: [ - "device-tests", "device-platinum-tests", + "device-tests", ], native_coverage: false, } diff --git a/services/inputflinger/tests/AndroidInputEventProtoConverter_test.cpp b/services/inputflinger/tests/AndroidInputEventProtoConverter_test.cpp new file mode 100644 index 0000000000..1fd6cee1eb --- /dev/null +++ b/services/inputflinger/tests/AndroidInputEventProtoConverter_test.cpp @@ -0,0 +1,586 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "../dispatcher/trace/AndroidInputEventProtoConverter.h" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +namespace android::inputdispatcher::trace { + +namespace { + +using testing::Return, testing::_; + +class MockProtoAxisValue { +public: + MOCK_METHOD(void, set_axis, (int32_t)); + MOCK_METHOD(void, set_value, (float)); +}; + +class MockProtoPointer { +public: + MOCK_METHOD(void, set_pointer_id, (uint32_t)); + MOCK_METHOD(void, set_tool_type, (int32_t)); + MOCK_METHOD(MockProtoAxisValue*, add_axis_value, ()); +}; + +class MockProtoMotion { +public: + MOCK_METHOD(void, set_event_id, (uint32_t)); + MOCK_METHOD(void, set_event_time_nanos, (int64_t)); + MOCK_METHOD(void, set_down_time_nanos, (int64_t)); + MOCK_METHOD(void, set_source, (uint32_t)); + MOCK_METHOD(void, set_action, (int32_t)); + MOCK_METHOD(void, set_device_id, (uint32_t)); + MOCK_METHOD(void, set_display_id, (uint32_t)); + MOCK_METHOD(void, set_classification, (int32_t)); + MOCK_METHOD(void, set_flags, (uint32_t)); + MOCK_METHOD(void, set_policy_flags, (uint32_t)); + MOCK_METHOD(void, set_button_state, (uint32_t)); + MOCK_METHOD(void, set_action_button, (uint32_t)); + MOCK_METHOD(void, set_cursor_position_x, (float)); + MOCK_METHOD(void, set_cursor_position_y, (float)); + MOCK_METHOD(void, set_meta_state, (uint32_t)); + MOCK_METHOD(void, set_precision_x, (float)); + MOCK_METHOD(void, set_precision_y, (float)); + MOCK_METHOD(MockProtoPointer*, add_pointer, ()); +}; + +class MockProtoKey { +public: + MOCK_METHOD(void, set_event_id, (uint32_t)); + MOCK_METHOD(void, set_event_time_nanos, (int64_t)); + MOCK_METHOD(void, set_down_time_nanos, (int64_t)); + MOCK_METHOD(void, set_source, (uint32_t)); + MOCK_METHOD(void, set_action, (int32_t)); + MOCK_METHOD(void, set_device_id, (uint32_t)); + MOCK_METHOD(void, set_display_id, (uint32_t)); + MOCK_METHOD(void, set_repeat_count, (uint32_t)); + MOCK_METHOD(void, set_flags, (uint32_t)); + MOCK_METHOD(void, set_policy_flags, (uint32_t)); + MOCK_METHOD(void, set_key_code, (uint32_t)); + MOCK_METHOD(void, set_scan_code, (uint32_t)); + MOCK_METHOD(void, set_meta_state, (uint32_t)); +}; + +class MockProtoDispatchPointer { +public: + MOCK_METHOD(void, set_pointer_id, (uint32_t)); + MOCK_METHOD(void, set_x_in_display, (float)); + MOCK_METHOD(void, set_y_in_display, (float)); + MOCK_METHOD(MockProtoAxisValue*, add_axis_value_in_window, ()); +}; + +class MockProtoDispatch { +public: + MOCK_METHOD(void, set_event_id, (uint32_t)); + MOCK_METHOD(void, set_vsync_id, (uint32_t)); + MOCK_METHOD(void, set_window_id, (uint32_t)); + MOCK_METHOD(void, set_resolved_flags, (uint32_t)); + MOCK_METHOD(MockProtoDispatchPointer*, add_dispatched_pointer, ()); +}; + +using TestProtoConverter = + AndroidInputEventProtoConverter<MockProtoMotion, MockProtoKey, MockProtoDispatch, + proto::AndroidInputEventConfig::Decoder>; + +TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent) { + TracedMotionEvent event{}; + event.id = 1; + event.eventTime = 2; + event.downTime = 3; + event.source = AINPUT_SOURCE_MOUSE; + event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS; + event.deviceId = 4; + event.displayId = ui::LogicalDisplayId(5); + event.classification = MotionClassification::PINCH; + event.flags = 6; + event.policyFlags = 7; + event.buttonState = 8; + event.actionButton = 9; + event.xCursorPosition = 10.0f; + event.yCursorPosition = 11.0f; + event.metaState = 12; + event.xPrecision = 13.0f; + event.yPrecision = 14.0f; + event.pointerProperties.emplace_back(PointerProperties{ + .id = 15, + .toolType = ToolType::MOUSE, + }); + event.pointerProperties.emplace_back(PointerProperties{ + .id = 16, + .toolType = ToolType::FINGER, + }); + event.pointerCoords.emplace_back(); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 17.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 18.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 19.0f); + event.pointerCoords.emplace_back(); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 20.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 21.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22.0f); + + testing::StrictMock<MockProtoMotion> proto; + testing::StrictMock<MockProtoPointer> pointer1; + testing::StrictMock<MockProtoPointer> pointer2; + testing::StrictMock<MockProtoAxisValue> axisValue1; + testing::StrictMock<MockProtoAxisValue> axisValue2; + testing::StrictMock<MockProtoAxisValue> axisValue3; + testing::StrictMock<MockProtoAxisValue> axisValue4; + testing::StrictMock<MockProtoAxisValue> axisValue5; + testing::StrictMock<MockProtoAxisValue> axisValue6; + + EXPECT_CALL(proto, set_event_id(1)); + EXPECT_CALL(proto, set_event_time_nanos(2)); + EXPECT_CALL(proto, set_down_time_nanos(3)); + EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE)); + EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS)); + EXPECT_CALL(proto, set_device_id(4)); + EXPECT_CALL(proto, set_display_id(5)); + EXPECT_CALL(proto, set_classification(AMOTION_EVENT_CLASSIFICATION_PINCH)); + EXPECT_CALL(proto, set_flags(6)); + EXPECT_CALL(proto, set_policy_flags(7)); + EXPECT_CALL(proto, set_button_state(8)); + EXPECT_CALL(proto, set_action_button(9)); + EXPECT_CALL(proto, set_cursor_position_x(10.0f)); + EXPECT_CALL(proto, set_cursor_position_y(11.0f)); + EXPECT_CALL(proto, set_meta_state(12)); + EXPECT_CALL(proto, set_precision_x(13.0f)); + EXPECT_CALL(proto, set_precision_y(14.0f)); + + EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2)); + + EXPECT_CALL(pointer1, set_pointer_id(15)); + EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE)); + EXPECT_CALL(pointer1, add_axis_value()) + .WillOnce(Return(&axisValue1)) + .WillOnce(Return(&axisValue2)) + .WillOnce(Return(&axisValue3)); + EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X)); + EXPECT_CALL(axisValue1, set_value(17.0f)); + EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y)); + EXPECT_CALL(axisValue2, set_value(18.0f)); + EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_PRESSURE)); + EXPECT_CALL(axisValue3, set_value(19.0f)); + + EXPECT_CALL(pointer2, set_pointer_id(16)); + EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER)); + EXPECT_CALL(pointer2, add_axis_value()) + .WillOnce(Return(&axisValue4)) + .WillOnce(Return(&axisValue5)) + .WillOnce(Return(&axisValue6)); + EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_X)); + EXPECT_CALL(axisValue4, set_value(20.0f)); + EXPECT_CALL(axisValue5, set_axis(AMOTION_EVENT_AXIS_Y)); + EXPECT_CALL(axisValue5, set_value(21.0f)); + EXPECT_CALL(axisValue6, set_axis(AMOTION_EVENT_AXIS_PRESSURE)); + EXPECT_CALL(axisValue6, set_value(22.0f)); + + TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/false); +} + +TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent_Redacted) { + TracedMotionEvent event{}; + event.id = 1; + event.eventTime = 2; + event.downTime = 3; + event.source = AINPUT_SOURCE_MOUSE; + event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS; + event.deviceId = 4; + event.displayId = ui::LogicalDisplayId(5); + event.classification = MotionClassification::PINCH; + event.flags = 6; + event.policyFlags = 7; + event.buttonState = 8; + event.actionButton = 9; + event.xCursorPosition = 10.0f; + event.yCursorPosition = 11.0f; + event.metaState = 12; + event.xPrecision = 13.0f; + event.yPrecision = 14.0f; + event.pointerProperties.emplace_back(PointerProperties{ + .id = 15, + .toolType = ToolType::MOUSE, + }); + event.pointerProperties.emplace_back(PointerProperties{ + .id = 16, + .toolType = ToolType::FINGER, + }); + event.pointerCoords.emplace_back(); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 17.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 18.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 19.0f); + event.pointerCoords.emplace_back(); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 20.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 21.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22.0f); + + testing::StrictMock<MockProtoMotion> proto; + testing::StrictMock<MockProtoPointer> pointer1; + testing::StrictMock<MockProtoPointer> pointer2; + testing::StrictMock<MockProtoAxisValue> axisValue1; + testing::StrictMock<MockProtoAxisValue> axisValue2; + testing::StrictMock<MockProtoAxisValue> axisValue3; + testing::StrictMock<MockProtoAxisValue> axisValue4; + testing::StrictMock<MockProtoAxisValue> axisValue5; + testing::StrictMock<MockProtoAxisValue> axisValue6; + + EXPECT_CALL(proto, set_event_id(1)); + EXPECT_CALL(proto, set_event_time_nanos(2)); + EXPECT_CALL(proto, set_down_time_nanos(3)); + EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE)); + EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS)); + EXPECT_CALL(proto, set_device_id(4)); + EXPECT_CALL(proto, set_display_id(5)); + EXPECT_CALL(proto, set_classification(AMOTION_EVENT_CLASSIFICATION_PINCH)); + EXPECT_CALL(proto, set_flags(6)); + EXPECT_CALL(proto, set_policy_flags(7)); + EXPECT_CALL(proto, set_button_state(8)); + EXPECT_CALL(proto, set_action_button(9)); + + EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2)); + + EXPECT_CALL(pointer1, set_pointer_id(15)); + EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE)); + EXPECT_CALL(pointer1, add_axis_value()) + .WillOnce(Return(&axisValue1)) + .WillOnce(Return(&axisValue2)) + .WillOnce(Return(&axisValue3)); + EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X)); + EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y)); + EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_PRESSURE)); + + EXPECT_CALL(pointer2, set_pointer_id(16)); + EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER)); + EXPECT_CALL(pointer2, add_axis_value()) + .WillOnce(Return(&axisValue4)) + .WillOnce(Return(&axisValue5)) + .WillOnce(Return(&axisValue6)); + EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_X)); + EXPECT_CALL(axisValue5, set_axis(AMOTION_EVENT_AXIS_Y)); + EXPECT_CALL(axisValue6, set_axis(AMOTION_EVENT_AXIS_PRESSURE)); + + // Redacted fields + EXPECT_CALL(proto, set_meta_state(_)).Times(0); + EXPECT_CALL(proto, set_cursor_position_x(_)).Times(0); + EXPECT_CALL(proto, set_cursor_position_y(_)).Times(0); + EXPECT_CALL(proto, set_precision_x(_)).Times(0); + EXPECT_CALL(proto, set_precision_y(_)).Times(0); + EXPECT_CALL(axisValue1, set_value(_)).Times(0); + EXPECT_CALL(axisValue2, set_value(_)).Times(0); + EXPECT_CALL(axisValue3, set_value(_)).Times(0); + EXPECT_CALL(axisValue4, set_value(_)).Times(0); + EXPECT_CALL(axisValue5, set_value(_)).Times(0); + EXPECT_CALL(axisValue6, set_value(_)).Times(0); + + TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/true); +} + +// Test any special handling for zero values for pointer events. +TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent_ZeroValues) { + TracedMotionEvent event{}; + event.id = 0; + event.eventTime = 0; + event.downTime = 0; + event.source = AINPUT_SOURCE_MOUSE; + event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS; + event.deviceId = 0; + event.displayId = ui::LogicalDisplayId(0); + event.classification = {}; + event.flags = 0; + event.policyFlags = 0; + event.buttonState = 0; + event.actionButton = 0; + event.xCursorPosition = 0.0f; + event.yCursorPosition = 0.0f; + event.metaState = 0; + event.xPrecision = 0.0f; + event.yPrecision = 0.0f; + event.pointerProperties.emplace_back(PointerProperties{ + .id = 0, + .toolType = ToolType::MOUSE, + }); + event.pointerProperties.emplace_back(PointerProperties{ + .id = 1, + .toolType = ToolType::FINGER, + }); + // Zero values for x and y axes are always traced for pointer events. + // However, zero values for other axes may not necessarily be traced. + event.pointerCoords.emplace_back(); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 0.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 1.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f); + event.pointerCoords.emplace_back(); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 0.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 0.0f); + event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f); + + testing::StrictMock<MockProtoMotion> proto; + testing::StrictMock<MockProtoPointer> pointer1; + testing::StrictMock<MockProtoPointer> pointer2; + testing::StrictMock<MockProtoAxisValue> axisValue1; + testing::StrictMock<MockProtoAxisValue> axisValue2; + testing::StrictMock<MockProtoAxisValue> axisValue3; + testing::StrictMock<MockProtoAxisValue> axisValue4; + + EXPECT_CALL(proto, set_event_id(0)); + EXPECT_CALL(proto, set_event_time_nanos(0)); + EXPECT_CALL(proto, set_down_time_nanos(0)); + EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE)); + EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS)); + EXPECT_CALL(proto, set_device_id(0)); + EXPECT_CALL(proto, set_display_id(0)); + EXPECT_CALL(proto, set_classification(0)); + EXPECT_CALL(proto, set_flags(0)); + EXPECT_CALL(proto, set_policy_flags(0)); + EXPECT_CALL(proto, set_button_state(0)); + EXPECT_CALL(proto, set_action_button(0)); + EXPECT_CALL(proto, set_cursor_position_x(0.0f)); + EXPECT_CALL(proto, set_cursor_position_y(0.0f)); + EXPECT_CALL(proto, set_meta_state(0)); + EXPECT_CALL(proto, set_precision_x(0.0f)); + EXPECT_CALL(proto, set_precision_y(0.0f)); + + EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2)); + + EXPECT_CALL(pointer1, set_pointer_id(0)); + EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE)); + EXPECT_CALL(pointer1, add_axis_value()) + .WillOnce(Return(&axisValue1)) + .WillOnce(Return(&axisValue2)); + EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X)); + EXPECT_CALL(axisValue1, set_value(0.0f)); + EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y)); + EXPECT_CALL(axisValue2, set_value(1.0f)); + + EXPECT_CALL(pointer2, set_pointer_id(1)); + EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER)); + EXPECT_CALL(pointer2, add_axis_value()) + .WillOnce(Return(&axisValue3)) + .WillOnce(Return(&axisValue4)); + EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_X)); + EXPECT_CALL(axisValue3, set_value(0.0f)); + EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_Y)); + EXPECT_CALL(axisValue4, set_value(0.0f)); + + TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/false); +} + +TEST(AndroidInputEventProtoConverterTest, ToProtoKeyEvent) { + TracedKeyEvent event{}; + event.id = 1; + event.eventTime = 2; + event.downTime = 3; + event.source = AINPUT_SOURCE_KEYBOARD; + event.action = AKEY_EVENT_ACTION_DOWN; + event.deviceId = 4; + event.displayId = ui::LogicalDisplayId(5); + event.repeatCount = 6; + event.flags = 7; + event.policyFlags = 8; + event.keyCode = 9; + event.scanCode = 10; + event.metaState = 11; + + testing::StrictMock<MockProtoKey> proto; + + EXPECT_CALL(proto, set_event_id(1)); + EXPECT_CALL(proto, set_event_time_nanos(2)); + EXPECT_CALL(proto, set_down_time_nanos(3)); + EXPECT_CALL(proto, set_source(AINPUT_SOURCE_KEYBOARD)); + EXPECT_CALL(proto, set_action(AKEY_EVENT_ACTION_DOWN)); + EXPECT_CALL(proto, set_device_id(4)); + EXPECT_CALL(proto, set_display_id(5)); + EXPECT_CALL(proto, set_repeat_count(6)); + EXPECT_CALL(proto, set_flags(7)); + EXPECT_CALL(proto, set_policy_flags(8)); + EXPECT_CALL(proto, set_key_code(9)); + EXPECT_CALL(proto, set_scan_code(10)); + EXPECT_CALL(proto, set_meta_state(11)); + + TestProtoConverter::toProtoKeyEvent(event, proto, /*isRedacted=*/false); +} + +TEST(AndroidInputEventProtoConverterTest, ToProtoKeyEvent_Redacted) { + TracedKeyEvent event{}; + event.id = 1; + event.eventTime = 2; + event.downTime = 3; + event.source = AINPUT_SOURCE_KEYBOARD; + event.action = AKEY_EVENT_ACTION_DOWN; + event.deviceId = 4; + event.displayId = ui::LogicalDisplayId(5); + event.repeatCount = 6; + event.flags = 7; + event.policyFlags = 8; + event.keyCode = 9; + event.scanCode = 10; + event.metaState = 11; + + testing::StrictMock<MockProtoKey> proto; + + EXPECT_CALL(proto, set_event_id(1)); + EXPECT_CALL(proto, set_event_time_nanos(2)); + EXPECT_CALL(proto, set_down_time_nanos(3)); + EXPECT_CALL(proto, set_source(AINPUT_SOURCE_KEYBOARD)); + EXPECT_CALL(proto, set_action(AKEY_EVENT_ACTION_DOWN)); + EXPECT_CALL(proto, set_device_id(4)); + EXPECT_CALL(proto, set_display_id(5)); + EXPECT_CALL(proto, set_repeat_count(6)); + EXPECT_CALL(proto, set_flags(7)); + EXPECT_CALL(proto, set_policy_flags(8)); + + // Redacted fields + EXPECT_CALL(proto, set_key_code(_)).Times(0); + EXPECT_CALL(proto, set_scan_code(_)).Times(0); + EXPECT_CALL(proto, set_meta_state(_)).Times(0); + + TestProtoConverter::toProtoKeyEvent(event, proto, /*isRedacted=*/true); +} + +TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Motion_IdentityTransform) { + TracedMotionEvent motion{}; + motion.pointerProperties.emplace_back(PointerProperties{ + .id = 4, + .toolType = ToolType::MOUSE, + }); + motion.pointerCoords.emplace_back(); + motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 5.0f); + motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 6.0f); + + WindowDispatchArgs args{}; + args.eventEntry = motion; + args.vsyncId = 1; + args.windowId = 2; + args.resolvedFlags = 3; + args.rawTransform = ui::Transform{}; + args.transform = ui::Transform{}; + + testing::StrictMock<MockProtoDispatch> proto; + testing::StrictMock<MockProtoDispatchPointer> pointer; + + EXPECT_CALL(proto, set_event_id(0)); + EXPECT_CALL(proto, set_vsync_id(1)); + EXPECT_CALL(proto, set_window_id(2)); + EXPECT_CALL(proto, set_resolved_flags(3)); + EXPECT_CALL(proto, add_dispatched_pointer()).WillOnce(Return(&pointer)); + EXPECT_CALL(pointer, set_pointer_id(4)); + + // Since we are using identity transforms, the axis values will be identical to those in the + // traced event, so they should not be traced here. + EXPECT_CALL(pointer, add_axis_value_in_window()).Times(0); + EXPECT_CALL(pointer, set_x_in_display(_)).Times(0); + EXPECT_CALL(pointer, set_y_in_display(_)).Times(0); + + TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/false); +} + +TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Motion_CustomTransform) { + TracedMotionEvent motion{}; + motion.pointerProperties.emplace_back(PointerProperties{ + .id = 4, + .toolType = ToolType::MOUSE, + }); + motion.pointerCoords.emplace_back(); + motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 8.0f); + motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 6.0f); + + WindowDispatchArgs args{}; + args.eventEntry = motion; + args.vsyncId = 1; + args.windowId = 2; + args.resolvedFlags = 3; + args.rawTransform.set(2, 0, 0, 0.5); + args.transform.set(1.0, 0, 0, 0.5); + + testing::StrictMock<MockProtoDispatch> proto; + testing::StrictMock<MockProtoDispatchPointer> pointer; + testing::StrictMock<MockProtoAxisValue> axisValue1; + + EXPECT_CALL(proto, set_event_id(0)); + EXPECT_CALL(proto, set_vsync_id(1)); + EXPECT_CALL(proto, set_window_id(2)); + EXPECT_CALL(proto, set_resolved_flags(3)); + EXPECT_CALL(proto, add_dispatched_pointer()).WillOnce(Return(&pointer)); + EXPECT_CALL(pointer, set_pointer_id(4)); + + // Only the transformed axis-values that differ from the traced event will be traced. + EXPECT_CALL(pointer, add_axis_value_in_window()).WillOnce(Return(&axisValue1)); + EXPECT_CALL(pointer, set_x_in_display(16.0f)); // MotionEvent::getRawX + EXPECT_CALL(pointer, set_y_in_display(3.0f)); // MotionEvent::getRawY + + EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_Y)); + EXPECT_CALL(axisValue1, set_value(3.0f)); + + TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/false); +} + +TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Motion_Redacted) { + TracedMotionEvent motion{}; + motion.pointerProperties.emplace_back(PointerProperties{ + .id = 4, + .toolType = ToolType::MOUSE, + }); + motion.pointerCoords.emplace_back(); + motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 5.0f); + motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 6.0f); + + WindowDispatchArgs args{}; + args.eventEntry = motion; + args.vsyncId = 1; + args.windowId = 2; + args.resolvedFlags = 3; + args.rawTransform = ui::Transform{}; + args.transform = ui::Transform{}; + + testing::StrictMock<MockProtoDispatch> proto; + + EXPECT_CALL(proto, set_event_id(0)); + EXPECT_CALL(proto, set_vsync_id(1)); + EXPECT_CALL(proto, set_window_id(2)); + EXPECT_CALL(proto, set_resolved_flags(3)); + + // Redacted fields + EXPECT_CALL(proto, add_dispatched_pointer()).Times(0); + + TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/true); +} + +TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Key) { + TracedKeyEvent key{}; + + WindowDispatchArgs args{}; + args.eventEntry = key; + args.vsyncId = 1; + args.windowId = 2; + args.resolvedFlags = 3; + args.rawTransform = ui::Transform{}; + args.transform = ui::Transform{}; + + testing::StrictMock<MockProtoDispatch> proto; + + EXPECT_CALL(proto, set_event_id(0)); + EXPECT_CALL(proto, set_vsync_id(1)); + EXPECT_CALL(proto, set_window_id(2)); + EXPECT_CALL(proto, set_resolved_flags(3)); + + TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/true); +} + +} // namespace + +} // namespace android::inputdispatcher::trace diff --git a/services/inputflinger/tests/CapturedTouchpadEventConverter_test.cpp b/services/inputflinger/tests/CapturedTouchpadEventConverter_test.cpp index 353011aa5c..c6246d9eec 100644 --- a/services/inputflinger/tests/CapturedTouchpadEventConverter_test.cpp +++ b/services/inputflinger/tests/CapturedTouchpadEventConverter_test.cpp @@ -33,8 +33,6 @@ #include "TestEventMatchers.h" #include "TestInputListener.h" -namespace input_flags = com::android::input::flags; - namespace android { using testing::AllOf; @@ -50,8 +48,6 @@ public: mReader(mFakeEventHub, mFakePolicy, mFakeListener), mDevice(newDevice()), mDeviceContext(*mDevice, EVENTHUB_ID) { - input_flags::include_relative_axis_values_for_captured_touchpads(true); - const size_t slotCount = 8; mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, 0, slotCount - 1, 0, 0, 0); mAccumulator.configure(mDeviceContext, slotCount, /*usingSlotsProtocol=*/true); diff --git a/services/inputflinger/tests/CursorInputMapper_test.cpp b/services/inputflinger/tests/CursorInputMapper_test.cpp index a31c4e96d7..594ee3b579 100644 --- a/services/inputflinger/tests/CursorInputMapper_test.cpp +++ b/services/inputflinger/tests/CursorInputMapper_test.cpp @@ -141,9 +141,9 @@ namespace vd_flags = android::companion::virtualdevice::flags; */ class CursorInputMapperUnitTestBase : public InputMapperUnitTest { protected: - void SetUp() override { SetUpWithBus(BUS_USB); } - void SetUpWithBus(int bus) override { - InputMapperUnitTest::SetUpWithBus(bus); + void SetUp() override { SetUp(BUS_USB, /*isExternal=*/false); } + void SetUp(int bus, bool isExternal) override { + InputMapperUnitTest::SetUp(bus, isExternal); // Current scan code state - all keys are UP by default setScanCodeState(KeyState::UP, @@ -1078,7 +1078,7 @@ TEST_F(CursorInputMapperUnitTest, ConfigureAccelerationWithAssociatedViewport) { ASSERT_GT(coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y), 20.f); // Disable acceleration for the display, and verify that acceleration is no longer applied. - mReaderConfiguration.displaysWithMousePointerAccelerationDisabled.emplace(DISPLAY_ID); + mReaderConfiguration.displaysWithMouseScalingDisabled.emplace(DISPLAY_ID); args += mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, InputReaderConfiguration::Change::POINTER_SPEED); args.clear(); @@ -1097,7 +1097,7 @@ TEST_F(CursorInputMapperUnitTest, ConfigureAccelerationOnDisplayChange) { DisplayViewport primaryViewport = createPrimaryViewport(ui::Rotation::Rotation0); mReaderConfiguration.setDisplayViewports({primaryViewport}); // Disable acceleration for the display. - mReaderConfiguration.displaysWithMousePointerAccelerationDisabled.emplace(DISPLAY_ID); + mReaderConfiguration.displaysWithMouseScalingDisabled.emplace(DISPLAY_ID); // Don't associate the device with the display yet. EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(std::nullopt)); @@ -1142,7 +1142,9 @@ constexpr nsecs_t MAX_BLUETOOTH_SMOOTHING_DELTA = ms2ns(32); class BluetoothCursorInputMapperUnitTest : public CursorInputMapperUnitTestBase { protected: - void SetUp() override { SetUpWithBus(BUS_BLUETOOTH); } + void SetUp() override { + CursorInputMapperUnitTestBase::SetUp(BUS_BLUETOOTH, /*isExternal=*/true); + } }; TEST_F(BluetoothCursorInputMapperUnitTest, TimestampSmoothening) { diff --git a/services/inputflinger/tests/DisplayTopologyGraph_test.cpp b/services/inputflinger/tests/DisplayTopologyGraph_test.cpp new file mode 100644 index 0000000000..fd2f21c4cb --- /dev/null +++ b/services/inputflinger/tests/DisplayTopologyGraph_test.cpp @@ -0,0 +1,120 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> +#include <input/DisplayTopologyGraph.h> + +#include <string> +#include <string_view> +#include <tuple> + +namespace android { + +namespace { + +constexpr ui::LogicalDisplayId DISPLAY_ID_1{1}; +constexpr ui::LogicalDisplayId DISPLAY_ID_2{2}; +constexpr int DENSITY_MEDIUM = 160; + +} // namespace + +using DisplayTopologyGraphTestFixtureParam = + std::tuple<std::string_view /*name*/, DisplayTopologyGraph, bool /*isValid*/>; + +class DisplayTopologyGraphTestFixture + : public testing::Test, + public testing::WithParamInterface<DisplayTopologyGraphTestFixtureParam> {}; + +TEST_P(DisplayTopologyGraphTestFixture, DisplayTopologyGraphTest) { + const auto& [_, displayTopology, isValid] = GetParam(); + EXPECT_EQ(isValid, displayTopology.isValid()); +} + +INSTANTIATE_TEST_SUITE_P( + DisplayTopologyGraphTest, DisplayTopologyGraphTestFixture, + testing::Values( + std::make_tuple( + "InvalidPrimaryDisplay", + DisplayTopologyGraph{.primaryDisplayId = ui::LogicalDisplayId::INVALID, + .graph = {}, + .displaysDensity = {}}, + false), + std::make_tuple("PrimaryDisplayNotInGraph", + DisplayTopologyGraph{.primaryDisplayId = DISPLAY_ID_1, + .graph = {}, + .displaysDensity = {}}, + false), + std::make_tuple("DisplayDensityMissing", + DisplayTopologyGraph{.primaryDisplayId = DISPLAY_ID_1, + .graph = {{DISPLAY_ID_1, {}}}, + .displaysDensity = {}}, + false), + std::make_tuple("ValidSingleDisplayTopology", + DisplayTopologyGraph{.primaryDisplayId = DISPLAY_ID_1, + .graph = {{DISPLAY_ID_1, {}}}, + .displaysDensity = {{DISPLAY_ID_1, + DENSITY_MEDIUM}}}, + true), + std::make_tuple( + "MissingReverseEdge", + DisplayTopologyGraph{.primaryDisplayId = DISPLAY_ID_1, + .graph = {{DISPLAY_ID_1, + {{DISPLAY_ID_2, + DisplayTopologyPosition::TOP, 0}}}}, + .displaysDensity = {{DISPLAY_ID_1, DENSITY_MEDIUM}, + {DISPLAY_ID_2, DENSITY_MEDIUM}}}, + false), + std::make_tuple( + "IncorrectReverseEdgeDirection", + DisplayTopologyGraph{.primaryDisplayId = DISPLAY_ID_1, + .graph = {{DISPLAY_ID_1, + {{DISPLAY_ID_2, + DisplayTopologyPosition::TOP, 0}}}, + {DISPLAY_ID_2, + {{DISPLAY_ID_1, + DisplayTopologyPosition::TOP, 0}}}}, + .displaysDensity = {{DISPLAY_ID_1, DENSITY_MEDIUM}, + {DISPLAY_ID_2, DENSITY_MEDIUM}}}, + false), + std::make_tuple( + "IncorrectReverseEdgeOffset", + DisplayTopologyGraph{.primaryDisplayId = DISPLAY_ID_1, + .graph = {{DISPLAY_ID_1, + {{DISPLAY_ID_2, + DisplayTopologyPosition::TOP, 10}}}, + {DISPLAY_ID_2, + {{DISPLAY_ID_1, + DisplayTopologyPosition::BOTTOM, 20}}}}, + .displaysDensity = {{DISPLAY_ID_1, DENSITY_MEDIUM}, + {DISPLAY_ID_2, DENSITY_MEDIUM}}}, + false), + std::make_tuple( + "ValidMultiDisplayTopology", + DisplayTopologyGraph{.primaryDisplayId = DISPLAY_ID_1, + .graph = {{DISPLAY_ID_1, + {{DISPLAY_ID_2, + DisplayTopologyPosition::TOP, 10}}}, + {DISPLAY_ID_2, + {{DISPLAY_ID_1, + DisplayTopologyPosition::BOTTOM, -10}}}}, + .displaysDensity = {{DISPLAY_ID_1, DENSITY_MEDIUM}, + {DISPLAY_ID_2, DENSITY_MEDIUM}}}, + true)), + [](const testing::TestParamInfo<DisplayTopologyGraphTestFixtureParam>& p) { + return std::string{std::get<0>(p.param)}; + }); + +} // namespace android diff --git a/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp b/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp index c4257a83c3..dcb148fe41 100644 --- a/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp +++ b/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp @@ -198,10 +198,6 @@ void FakeInputDispatcherPolicy::assertNotifyInputChannelBrokenWasCalled(const sp ASSERT_EQ(token, *receivedToken); } -void FakeInputDispatcherPolicy::setInterceptKeyTimeout(std::chrono::milliseconds timeout) { - mInterceptKeyTimeout = timeout; -} - std::chrono::nanoseconds FakeInputDispatcherPolicy::getKeyWaitingForEventsTimeout() { return 500ms; } @@ -210,8 +206,9 @@ void FakeInputDispatcherPolicy::setStaleEventTimeout(std::chrono::nanoseconds ti mStaleEventTimeout = timeout; } -void FakeInputDispatcherPolicy::setConsumeKeyBeforeDispatching(bool consumeKeyBeforeDispatching) { - mConsumeKeyBeforeDispatching = consumeKeyBeforeDispatching; +void FakeInputDispatcherPolicy::setInterceptKeyBeforeDispatchingResult( + std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> result) { + mInterceptKeyBeforeDispatchingResult = result; } void FakeInputDispatcherPolicy::assertFocusedDisplayNotified(ui::LogicalDisplayId expectedDisplay) { @@ -404,7 +401,9 @@ bool FakeInputDispatcherPolicy::filterInputEvent(const InputEvent& inputEvent, void FakeInputDispatcherPolicy::interceptKeyBeforeQueueing(const KeyEvent& inputEvent, uint32_t&) { if (inputEvent.getAction() == AKEY_EVENT_ACTION_UP) { // Clear intercept state when we handled the event. - mInterceptKeyTimeout = 0ms; + if (std::holds_alternative<nsecs_t>(mInterceptKeyBeforeDispatchingResult)) { + mInterceptKeyBeforeDispatchingResult = nsecs_t(0); + } } } @@ -414,17 +413,20 @@ void FakeInputDispatcherPolicy::interceptMotionBeforeQueueing(ui::LogicalDisplay std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, uint32_t) { - if (mConsumeKeyBeforeDispatching) { - return inputdispatcher::KeyEntry::InterceptKeyResult::SKIP; + if (std::holds_alternative<inputdispatcher::KeyEntry::InterceptKeyResult>( + mInterceptKeyBeforeDispatchingResult)) { + return mInterceptKeyBeforeDispatchingResult; } - nsecs_t delay = std::chrono::nanoseconds(mInterceptKeyTimeout).count(); + nsecs_t delay = + std::chrono::nanoseconds(std::get<nsecs_t>(mInterceptKeyBeforeDispatchingResult)) + .count(); if (delay == 0) { return inputdispatcher::KeyEntry::InterceptKeyResult::CONTINUE; } // Clear intercept state so we could dispatch the event in next wake. - mInterceptKeyTimeout = 0ms; + mInterceptKeyBeforeDispatchingResult = nsecs_t(0); return delay; } diff --git a/services/inputflinger/tests/FakeInputDispatcherPolicy.h b/services/inputflinger/tests/FakeInputDispatcherPolicy.h index c387eacb51..b151686e9b 100644 --- a/services/inputflinger/tests/FakeInputDispatcherPolicy.h +++ b/services/inputflinger/tests/FakeInputDispatcherPolicy.h @@ -96,10 +96,6 @@ public: void assertDropTargetEquals(const InputDispatcherInterface& dispatcher, const sp<IBinder>& targetToken); void assertNotifyInputChannelBrokenWasCalled(const sp<IBinder>& token); - /** - * Set policy timeout. A value of zero means next key will not be intercepted. - */ - void setInterceptKeyTimeout(std::chrono::milliseconds timeout); std::chrono::nanoseconds getKeyWaitingForEventsTimeout() override; void setStaleEventTimeout(std::chrono::nanoseconds timeout); void assertUserActivityNotPoked(); @@ -116,7 +112,12 @@ public: void setUnhandledKeyHandler(std::function<std::optional<KeyEvent>(const KeyEvent&)> handler); void assertUnhandledKeyReported(int32_t keycode); void assertUnhandledKeyNotReported(); - void setConsumeKeyBeforeDispatching(bool consumeKeyBeforeDispatching); + /** + * Set policy timeout or the interception result. + * A timeout value of zero means next key will not be intercepted. + */ + void setInterceptKeyBeforeDispatchingResult( + std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> result); void assertFocusedDisplayNotified(ui::LogicalDisplayId expectedDisplay); private: @@ -145,11 +146,10 @@ private: std::condition_variable mNotifyUserActivity; std::queue<UserActivityPokeEvent> mUserActivityPokeEvents; - std::chrono::milliseconds mInterceptKeyTimeout = 0ms; - std::chrono::nanoseconds mStaleEventTimeout = 1000ms; - bool mConsumeKeyBeforeDispatching = false; + std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> + mInterceptKeyBeforeDispatchingResult; BlockingQueue<std::pair<int32_t /*deviceId*/, std::set<gui::Uid>>> mNotifiedInteractions; diff --git a/services/inputflinger/tests/FakeInputReaderPolicy.cpp b/services/inputflinger/tests/FakeInputReaderPolicy.cpp index 67b1e8c249..5a14f4bdfe 100644 --- a/services/inputflinger/tests/FakeInputReaderPolicy.cpp +++ b/services/inputflinger/tests/FakeInputReaderPolicy.cpp @@ -31,6 +31,30 @@ static const int HW_TIMEOUT_MULTIPLIER = base::GetIntProperty("ro.hw_timeout_mul } // namespace +DisplayViewport createViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height, + ui::Rotation orientation, bool isActive, const std::string& uniqueId, + std::optional<uint8_t> physicalPort, ViewportType type) { + const bool isRotated = orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270; + DisplayViewport v; + v.displayId = displayId; + v.orientation = orientation; + v.logicalLeft = 0; + v.logicalTop = 0; + v.logicalRight = isRotated ? height : width; + v.logicalBottom = isRotated ? width : height; + v.physicalLeft = 0; + v.physicalTop = 0; + v.physicalRight = isRotated ? height : width; + v.physicalBottom = isRotated ? width : height; + v.deviceWidth = isRotated ? height : width; + v.deviceHeight = isRotated ? width : height; + v.isActive = isActive; + v.uniqueId = uniqueId; + v.physicalPort = physicalPort; + v.type = type; + return v; +}; + void FakeInputReaderPolicy::assertInputDevicesChanged() { waitForInputDevices( [](bool devicesChanged) { @@ -115,33 +139,6 @@ void FakeInputReaderPolicy::addDisplayViewport(DisplayViewport viewport) { mConfig.setDisplayViewports(mViewports); } -void FakeInputReaderPolicy::addDisplayViewport(ui::LogicalDisplayId displayId, int32_t width, - int32_t height, ui::Rotation orientation, - bool isActive, const std::string& uniqueId, - std::optional<uint8_t> physicalPort, - ViewportType type) { - const bool isRotated = orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270; - DisplayViewport v; - v.displayId = displayId; - v.orientation = orientation; - v.logicalLeft = 0; - v.logicalTop = 0; - v.logicalRight = isRotated ? height : width; - v.logicalBottom = isRotated ? width : height; - v.physicalLeft = 0; - v.physicalTop = 0; - v.physicalRight = isRotated ? height : width; - v.physicalBottom = isRotated ? width : height; - v.deviceWidth = isRotated ? height : width; - v.deviceHeight = isRotated ? width : height; - v.isActive = isActive; - v.uniqueId = uniqueId; - v.physicalPort = physicalPort; - v.type = type; - - addDisplayViewport(v); -} - bool FakeInputReaderPolicy::updateViewport(const DisplayViewport& viewport) { size_t count = mViewports.size(); for (size_t i = 0; i < count; i++) { diff --git a/services/inputflinger/tests/FakeInputReaderPolicy.h b/services/inputflinger/tests/FakeInputReaderPolicy.h index 42c956789b..9dce31a8a6 100644 --- a/services/inputflinger/tests/FakeInputReaderPolicy.h +++ b/services/inputflinger/tests/FakeInputReaderPolicy.h @@ -31,6 +31,10 @@ namespace android { +DisplayViewport createViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height, + ui::Rotation orientation, bool isActive, const std::string& uniqueId, + std::optional<uint8_t> physicalPort, ViewportType type); + class FakeInputReaderPolicy : public InputReaderPolicyInterface { protected: virtual ~FakeInputReaderPolicy() {} @@ -50,9 +54,6 @@ public: std::optional<DisplayViewport> getDisplayViewportByType(ViewportType type) const; std::optional<DisplayViewport> getDisplayViewportByPort(uint8_t displayPort) const; void addDisplayViewport(DisplayViewport viewport); - void addDisplayViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height, - ui::Rotation orientation, bool isActive, const std::string& uniqueId, - std::optional<uint8_t> physicalPort, ViewportType type); bool updateViewport(const DisplayViewport& viewport); void addExcludedDeviceName(const std::string& deviceName); void addInputPortAssociation(const std::string& inputPort, uint8_t displayPort); diff --git a/services/inputflinger/tests/FakeWindows.h b/services/inputflinger/tests/FakeWindows.h index 3a3238a6ad..54dc25aaa0 100644 --- a/services/inputflinger/tests/FakeWindows.h +++ b/services/inputflinger/tests/FakeWindows.h @@ -144,10 +144,6 @@ public: mInfo.setInputConfig(InputConfig::PAUSE_DISPATCHING, paused); } - inline void setPreventSplitting(bool preventSplitting) { - mInfo.setInputConfig(InputConfig::PREVENT_SPLITTING, preventSplitting); - } - inline void setSlippery(bool slippery) { mInfo.setInputConfig(InputConfig::SLIPPERY, slippery); } diff --git a/services/inputflinger/tests/GestureConverter_test.cpp b/services/inputflinger/tests/GestureConverter_test.cpp index 8fa439d633..35310a529b 100644 --- a/services/inputflinger/tests/GestureConverter_test.cpp +++ b/services/inputflinger/tests/GestureConverter_test.cpp @@ -15,11 +15,15 @@ */ #include <memory> +#include <tuple> +#include <android-base/result-gmock.h> +#include <android-base/result.h> #include <com_android_input_flags.h> #include <flag_macros.h> #include <gestures/GestureConverter.h> #include <gtest/gtest.h> +#include <input/InputVerifier.h> #include "FakeEventHub.h" #include "FakeInputReaderPolicy.h" @@ -38,13 +42,15 @@ namespace input_flags = com::android::input::flags; namespace { -const auto TOUCHPAD_PALM_REJECTION = - ACONFIG_FLAG(input_flags, enable_touchpad_typing_palm_rejection); const auto TOUCHPAD_PALM_REJECTION_V2 = ACONFIG_FLAG(input_flags, enable_v2_touchpad_typing_palm_rejection); +constexpr stime_t ARBITRARY_GESTURE_TIME = 1.2; +constexpr stime_t GESTURE_TIME = ARBITRARY_GESTURE_TIME; + } // namespace +using android::base::testing::Ok; using testing::AllOf; using testing::Each; using testing::ElementsAre; @@ -55,9 +61,8 @@ class GestureConverterTest : public testing::Test { protected: static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000; static constexpr int32_t EVENTHUB_ID = 1; - static constexpr stime_t ARBITRARY_GESTURE_TIME = 1.2; - void SetUp() { + GestureConverterTest() { mFakeEventHub = std::make_unique<FakeEventHub>(); mFakePolicy = sp<FakeInputReaderPolicy>::make(); mFakeListener = std::make_unique<TestInputListener>(); @@ -1454,7 +1459,6 @@ TEST_F(GestureConverterTest, Click) { } TEST_F_WITH_FLAGS(GestureConverterTest, TapWithTapToClickDisabled, - REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION), REQUIRES_FLAGS_DISABLED(TOUCHPAD_PALM_REJECTION_V2)) { nsecs_t currentTime = ARBITRARY_GESTURE_TIME; @@ -1567,8 +1571,7 @@ TEST_F_WITH_FLAGS(GestureConverterTest, TapWithTapToClickDisabledWithDelay, ASSERT_THAT(args, Each(VariantWith<NotifyMotionArgs>(WithRelativeMotion(0.f, 0.f)))); } -TEST_F_WITH_FLAGS(GestureConverterTest, ClickWithTapToClickDisabled, - REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION)) { +TEST_F(GestureConverterTest, ClickWithTapToClickDisabled) { // Click should still produce button press/release events mReader->getContext()->setPreventingTouchpadTaps(true); @@ -1637,8 +1640,7 @@ TEST_F_WITH_FLAGS(GestureConverterTest, ClickWithTapToClickDisabled, ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps()); } -TEST_F_WITH_FLAGS(GestureConverterTest, MoveEnablesTapToClick, - REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION)) { +TEST_F(GestureConverterTest, MoveEnablesTapToClick) { // initially disable tap-to-click mReader->getContext()->setPreventingTouchpadTaps(true); @@ -1698,4 +1700,136 @@ TEST_F_WITH_FLAGS(GestureConverterTest, KeypressCancelsHoverMove, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE)))); } +/** + * Tests that the event stream output by the converter remains consistent when converting sequences + * of Gestures interleaved with button presses in various ways. Takes tuples of three Gestures: one + * that starts the gesture sequence, one that continues it (which may or may not be used in a + * particular test case), and one that ends it. + */ +class GestureConverterConsistencyTest + : public GestureConverterTest, + public testing::WithParamInterface<std::tuple<Gesture, Gesture, Gesture>> { +protected: + GestureConverterConsistencyTest() + : GestureConverterTest(), + mParamStartGesture(std::get<0>(GetParam())), + mParamContinueGesture(std::get<1>(GetParam())), + mParamEndGesture(std::get<2>(GetParam())), + mDeviceContext(*mDevice, EVENTHUB_ID), + mConverter(*mReader->getContext(), mDeviceContext, DEVICE_ID) { + mConverter.setDisplayId(ui::LogicalDisplayId::DEFAULT); + input_flags::enable_button_state_verification(true); + mVerifier = std::make_unique<InputVerifier>("Test verifier"); + } + + base::Result<void> processMotionArgs(NotifyMotionArgs arg) { + return mVerifier->processMovement(arg.deviceId, arg.source, arg.action, arg.actionButton, + arg.getPointerCount(), arg.pointerProperties.data(), + arg.pointerCoords.data(), arg.flags, arg.buttonState); + } + + void verifyArgsFromGesture(const Gesture& gesture, size_t gestureIndex) { + std::list<NotifyArgs> args = + mConverter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, gesture); + for (const NotifyArgs& notifyArg : args) { + const NotifyMotionArgs& arg = std::get<NotifyMotionArgs>(notifyArg); + ASSERT_THAT(processMotionArgs(arg), Ok()) + << "when processing " << arg.dump() << "\nfrom gesture " << gestureIndex << ": " + << gesture.String(); + } + } + + void verifyArgsFromGestures(const std::vector<Gesture>& gestures) { + for (size_t i = 0; i < gestures.size(); i++) { + ASSERT_NO_FATAL_FAILURE(verifyArgsFromGesture(gestures[i], i)); + } + } + + Gesture mParamStartGesture; + Gesture mParamContinueGesture; + Gesture mParamEndGesture; + + InputDeviceContext mDeviceContext; + GestureConverter mConverter; + std::unique_ptr<InputVerifier> mVerifier; +}; + +TEST_P(GestureConverterConsistencyTest, ButtonChangesDuringGesture) { + verifyArgsFromGestures({ + mParamStartGesture, + Gesture(kGestureButtonsChange, GESTURE_TIME, GESTURE_TIME, + /*down=*/GESTURES_BUTTON_LEFT, /*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false), + mParamContinueGesture, + Gesture(kGestureButtonsChange, GESTURE_TIME, GESTURE_TIME, + /*down=*/GESTURES_BUTTON_NONE, /*up=*/GESTURES_BUTTON_LEFT, /*is_tap=*/false), + mParamEndGesture, + }); +} + +TEST_P(GestureConverterConsistencyTest, ButtonDownDuringGestureAndUpAfterEnd) { + verifyArgsFromGestures({ + mParamStartGesture, + Gesture(kGestureButtonsChange, GESTURE_TIME, GESTURE_TIME, + /*down=*/GESTURES_BUTTON_LEFT, /*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false), + mParamContinueGesture, + mParamEndGesture, + Gesture(kGestureButtonsChange, GESTURE_TIME, GESTURE_TIME, + /*down=*/GESTURES_BUTTON_NONE, /*up=*/GESTURES_BUTTON_LEFT, /*is_tap=*/false), + }); +} + +TEST_P(GestureConverterConsistencyTest, GestureStartAndEndDuringButtonDown) { + verifyArgsFromGestures({ + Gesture(kGestureButtonsChange, GESTURE_TIME, GESTURE_TIME, + /*down=*/GESTURES_BUTTON_LEFT, /*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false), + mParamStartGesture, + mParamContinueGesture, + mParamEndGesture, + Gesture(kGestureButtonsChange, GESTURE_TIME, GESTURE_TIME, + /*down=*/GESTURES_BUTTON_NONE, /*up=*/GESTURES_BUTTON_LEFT, /*is_tap=*/false), + }); +} + +TEST_P(GestureConverterConsistencyTest, GestureStartsWhileButtonDownAndEndsAfterUp) { + verifyArgsFromGestures({ + Gesture(kGestureButtonsChange, GESTURE_TIME, GESTURE_TIME, + /*down=*/GESTURES_BUTTON_LEFT, /*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false), + mParamStartGesture, + mParamContinueGesture, + Gesture(kGestureButtonsChange, GESTURE_TIME, GESTURE_TIME, + /*down=*/GESTURES_BUTTON_NONE, /*up=*/GESTURES_BUTTON_LEFT, /*is_tap=*/false), + mParamEndGesture, + }); +} + +TEST_P(GestureConverterConsistencyTest, TapToClickDuringGesture) { + verifyArgsFromGestures({ + mParamStartGesture, + Gesture(kGestureButtonsChange, GESTURE_TIME, GESTURE_TIME, + /*down=*/GESTURES_BUTTON_LEFT, /*up=*/GESTURES_BUTTON_LEFT, /*is_tap=*/false), + mParamEndGesture, + }); +} + +INSTANTIATE_TEST_SUITE_P( + GestureAndButtonInterleavings, GestureConverterConsistencyTest, + testing::Values( + std::make_tuple(Gesture(kGestureScroll, GESTURE_TIME, GESTURE_TIME, 0, -10), + Gesture(kGestureScroll, GESTURE_TIME, GESTURE_TIME, 0, -5), + Gesture(kGestureFling, GESTURE_TIME, GESTURE_TIME, 1, 1, + GESTURES_FLING_START)), + std::make_tuple(Gesture(kGestureSwipe, GESTURE_TIME, GESTURE_TIME, 0, -10), + Gesture(kGestureSwipe, GESTURE_TIME, GESTURE_TIME, 0, 5), + Gesture(kGestureSwipeLift, GESTURE_TIME, GESTURE_TIME)), + std::make_tuple(Gesture(kGestureFourFingerSwipe, GESTURE_TIME, GESTURE_TIME, 0, + -10), + Gesture(kGestureFourFingerSwipe, GESTURE_TIME, GESTURE_TIME, 0, 5), + Gesture(kGestureFourFingerSwipeLift, GESTURE_TIME, GESTURE_TIME)), + std::make_tuple(Gesture(kGesturePinch, GESTURE_TIME, GESTURE_TIME, + /*dz=*/1, GESTURES_ZOOM_START), + Gesture(kGesturePinch, GESTURE_TIME, GESTURE_TIME, + /*dz=*/0.8, GESTURES_ZOOM_UPDATE), + Gesture(kGesturePinch, GESTURE_TIME, GESTURE_TIME, + /*dz=*/1, GESTURES_ZOOM_END)))); + } // namespace android diff --git a/services/inputflinger/tests/HardwareStateConverter_test.cpp b/services/inputflinger/tests/HardwareStateConverter_test.cpp index 34c81fcf02..ee125bb2cb 100644 --- a/services/inputflinger/tests/HardwareStateConverter_test.cpp +++ b/services/inputflinger/tests/HardwareStateConverter_test.cpp @@ -33,13 +33,6 @@ namespace android { -namespace { - -const auto REPORT_PALMS = - ACONFIG_FLAG(com::android::input::flags, report_palms_to_gestures_library); - -} // namespace - class HardwareStateConverterTest : public testing::Test { public: HardwareStateConverterTest() @@ -201,24 +194,7 @@ TEST_F(HardwareStateConverterTest, TwoFingers) { EXPECT_EQ(0u, finger2.flags); } -TEST_F_WITH_FLAGS(HardwareStateConverterTest, OnePalmDisableReportPalms, - REQUIRES_FLAGS_DISABLED(REPORT_PALMS)) { - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100); - - processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1); - processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1); - std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME); - ASSERT_TRUE(schs.has_value()); - EXPECT_EQ(0, schs->state.touch_cnt); - EXPECT_EQ(0, schs->state.finger_cnt); -} - -TEST_F_WITH_FLAGS(HardwareStateConverterTest, OnePalmEnableReportPalms, - REQUIRES_FLAGS_ENABLED(REPORT_PALMS)) { +TEST_F(HardwareStateConverterTest, OnePalm) { processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0); processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM); processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123); @@ -234,54 +210,7 @@ TEST_F_WITH_FLAGS(HardwareStateConverterTest, OnePalmEnableReportPalms, EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type); } -TEST_F_WITH_FLAGS(HardwareStateConverterTest, OneFingerTurningIntoAPalmDisableReportPalms, - REQUIRES_FLAGS_DISABLED(REPORT_PALMS)) { - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100); - - processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1); - processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1); - - std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME); - ASSERT_TRUE(schs.has_value()); - EXPECT_EQ(1, schs->state.touch_cnt); - EXPECT_EQ(1, schs->state.finger_cnt); - - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 51); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 99); - - schs = processSync(ARBITRARY_TIME); - ASSERT_TRUE(schs.has_value()); - EXPECT_EQ(0, schs->state.touch_cnt); - ASSERT_EQ(0, schs->state.finger_cnt); - - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 53); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 97); - - schs = processSync(ARBITRARY_TIME); - ASSERT_TRUE(schs.has_value()); - EXPECT_EQ(0, schs->state.touch_cnt); - EXPECT_EQ(0, schs->state.finger_cnt); - - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 55); - processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 95); - schs = processSync(ARBITRARY_TIME); - ASSERT_TRUE(schs.has_value()); - EXPECT_EQ(1, schs->state.touch_cnt); - ASSERT_EQ(1, schs->state.finger_cnt); - const FingerState& newFinger = schs->state.fingers[0]; - EXPECT_EQ(123, newFinger.tracking_id); - EXPECT_NEAR(55, newFinger.position_x, EPSILON); - EXPECT_NEAR(95, newFinger.position_y, EPSILON); -} - -TEST_F_WITH_FLAGS(HardwareStateConverterTest, OneFingerTurningIntoAPalmEnableReportPalms, - REQUIRES_FLAGS_ENABLED(REPORT_PALMS)) { +TEST_F(HardwareStateConverterTest, OneFingerTurningIntoAPalmEnableReportPalms) { processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0); processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123); diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index fb67cebf29..835b677e1e 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -19,6 +19,7 @@ #include "FakeInputDispatcherPolicy.h" #include "FakeInputTracingBackend.h" #include "FakeWindows.h" +#include "ScopedFlagOverride.h" #include "TestEventMatchers.h" #include <NotifyArgsBuilders.h> @@ -138,40 +139,6 @@ static KeyEvent getTestKeyEvent() { return event; } -/** - * Provide a local override for a flag value. The value is restored when the object of this class - * goes out of scope. - * This class is not intended to be used directly, because its usage is cumbersome. - * Instead, a wrapper macro SCOPED_FLAG_OVERRIDE is provided. - */ -class ScopedFlagOverride { -public: - ScopedFlagOverride(std::function<bool()> read, std::function<void(bool)> write, bool value) - : mInitialValue(read()), mWriteValue(write) { - mWriteValue(value); - } - ~ScopedFlagOverride() { mWriteValue(mInitialValue); } - -private: - const bool mInitialValue; - std::function<void(bool)> mWriteValue; -}; - -typedef bool (*readFlagValueFunction)(); -typedef void (*writeFlagValueFunction)(bool); - -/** - * Use this macro to locally override a flag value. - * Example usage: - * SCOPED_FLAG_OVERRIDE(enable_multi_device_same_window_stream, false); - * Note: this works by creating a local variable in your current scope. Don't call this twice for - * the same flag, because the variable names will clash! - */ -#define SCOPED_FLAG_OVERRIDE(NAME, VALUE) \ - readFlagValueFunction read##NAME = com::android::input::flags::NAME; \ - writeFlagValueFunction write##NAME = com::android::input::flags::NAME; \ - ScopedFlagOverride override##NAME(read##NAME, write##NAME, (VALUE)) - } // namespace // --- InputDispatcherTest --- @@ -1215,22 +1182,17 @@ TEST_F(InputDispatcherTest, MultiDeviceTouchTransferWithWallpaperWindows) { WithFlags(EXPECTED_WALLPAPER_FLAGS | AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE))); } -class ShouldSplitTouchFixture : public InputDispatcherTest, - public ::testing::WithParamInterface<bool> {}; -INSTANTIATE_TEST_SUITE_P(InputDispatcherTest, ShouldSplitTouchFixture, - ::testing::Values(true, false)); /** * A single window that receives touch (on top), and a wallpaper window underneath it. * The top window gets a multitouch gesture. * Ensure that wallpaper gets the same gesture. */ -TEST_P(ShouldSplitTouchFixture, WallpaperWindowReceivesMultiTouch) { +TEST_F(InputDispatcherTest, WallpaperWindowReceivesMultiTouch) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> foregroundWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Foreground", ui::LogicalDisplayId::DEFAULT); foregroundWindow->setDupTouchToWallpaper(true); - foregroundWindow->setPreventSplitting(GetParam()); sp<FakeWindowHandle> wallpaperWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Wallpaper", @@ -1575,6 +1537,60 @@ TEST_F(InputDispatcherTest, HoverEventInconsistentPolicy) { window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT)); } +// Still send inject motion events to window which already be touched. +TEST_F(InputDispatcherTest, AlwaysDispatchInjectMotionEventWhenAlreadyDownForWindow) { + std::shared_ptr<FakeApplicationHandle> application1 = std::make_shared<FakeApplicationHandle>(); + sp<FakeWindowHandle> window1 = + sp<FakeWindowHandle>::make(application1, mDispatcher, "window1", + ui::LogicalDisplayId::DEFAULT); + window1->setFrame(Rect(0, 0, 100, 100)); + window1->setWatchOutsideTouch(false); + + std::shared_ptr<FakeApplicationHandle> application2 = std::make_shared<FakeApplicationHandle>(); + sp<FakeWindowHandle> window2 = + sp<FakeWindowHandle>::make(application2, mDispatcher, "window2", + ui::LogicalDisplayId::DEFAULT); + window2->setFrame(Rect(50, 50, 100, 100)); + window2->setWatchOutsideTouch(true); + mDispatcher->onWindowInfosChanged({{*window2->getInfo(), *window1->getInfo()}, {}, 0, 0}); + + std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT; + InputEventInjectionSync injectionMode = InputEventInjectionSync::WAIT_FOR_RESULT; + std::optional<gui::Uid> targetUid = {}; + uint32_t policyFlags = DEFAULT_POLICY_FLAGS; + + const MotionEvent eventDown1 = MotionEventBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60)).deviceId(-1) + .build(); + injectMotionEvent(*mDispatcher, eventDown1, injectionTimeout, injectionMode, targetUid, + policyFlags); + window2->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); + + const MotionEvent eventUp1 = MotionEventBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60)).deviceId(-1) + .downTime(eventDown1.getDownTime()).build(); + // Inject UP event, without the POLICY_FLAG_PASS_TO_USER (to simulate policy behaviour + // when screen is off). + injectMotionEvent(*mDispatcher, eventUp1, injectionTimeout, injectionMode, targetUid, + /*policyFlags=*/0); + window2->consumeMotionEvent(WithMotionAction(ACTION_UP)); + const MotionEvent eventDown2 = MotionEventBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(0, ToolType::FINGER).x(40).y(40)).deviceId(-1) + .build(); + injectMotionEvent(*mDispatcher, eventDown2, injectionTimeout, injectionMode, targetUid, + policyFlags); + window1->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); + window2->consumeMotionEvent(WithMotionAction(ACTION_OUTSIDE)); + + const MotionEvent eventUp2 = MotionEventBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60)).deviceId(-1) + .downTime(eventDown2.getDownTime()).build(); + injectMotionEvent(*mDispatcher, eventUp2, injectionTimeout, injectionMode, targetUid, + /*policyFlags=*/0); + window1->consumeMotionEvent(WithMotionAction(ACTION_UP)); + window2->assertNoEvents(); +} + /** * Two windows: a window on the left and a window on the right. * Mouse is hovered from the right window into the left window. @@ -4260,17 +4276,15 @@ TEST_F(InputDispatcherTest, SplitTouchesSendCorrectActionDownTime) { } /** - * When events are not split, the downTime should be adjusted such that the downTime corresponds + * When events are split, the downTime should be adjusted such that the downTime corresponds * to the event time of the first ACTION_DOWN. If a new window appears, it should not affect - * the event routing because the first window prevents splitting. + * the event routing unless pointers are delivered to the new window. */ TEST_F(InputDispatcherTest, SplitTouchesSendCorrectActionDownTimeForNewWindow) { - SCOPED_FLAG_OVERRIDE(split_all_touches, false); std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window1 = sp<FakeWindowHandle>::make(application, mDispatcher, "Window1", DISPLAY_ID); window1->setTouchableRegion(Region{{0, 0, 100, 100}}); - window1->setPreventSplitting(true); sp<FakeWindowHandle> window2 = sp<FakeWindowHandle>::make(application, mDispatcher, "Window2", DISPLAY_ID); @@ -4290,13 +4304,18 @@ TEST_F(InputDispatcherTest, SplitTouchesSendCorrectActionDownTimeForNewWindow) { // Second window is added mDispatcher->onWindowInfosChanged({{*window1->getInfo(), *window2->getInfo()}, {}, 0, 0}); - // Now touch down on the window with another pointer - mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) - .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) - .pointer(PointerBuilder(1, ToolType::FINGER).x(150).y(50)) - .downTime(downArgs.downTime) - .build()); - window1->consumeMotionPointerDown(1, AllOf(WithDownTime(downArgs.downTime))); + // Now touch down on the new window with another pointer + NotifyMotionArgs pointerDownArgs = + MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) + .pointer(PointerBuilder(1, ToolType::FINGER).x(150).y(50)) + .downTime(downArgs.downTime) + .build(); + mDispatcher->notifyMotion(pointerDownArgs); + window1->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithPointerCount(1), + WithDownTime(downArgs.downTime))); + window2->consumeMotionEvent( + AllOf(WithMotionAction(ACTION_DOWN), WithDownTime(pointerDownArgs.eventTime))); // Finish the gesture mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN) @@ -4304,11 +4323,16 @@ TEST_F(InputDispatcherTest, SplitTouchesSendCorrectActionDownTimeForNewWindow) { .pointer(PointerBuilder(1, ToolType::FINGER).x(150).y(50)) .downTime(downArgs.downTime) .build()); + window1->consumeMotionEvent( + AllOf(WithMotionAction(ACTION_MOVE), WithDownTime(downArgs.downTime))); + window2->consumeMotionEvent( + AllOf(WithMotionAction(ACTION_UP), WithDownTime(pointerDownArgs.eventTime))); + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) .downTime(downArgs.downTime) .build()); - window1->consumeMotionPointerUp(1, AllOf(WithDownTime(downArgs.downTime))); + window1->consumeMotionEvent( AllOf(WithMotionAction(ACTION_UP), WithDownTime(downArgs.downTime))); window2->assertNoEvents(); @@ -4317,13 +4341,12 @@ TEST_F(InputDispatcherTest, SplitTouchesSendCorrectActionDownTimeForNewWindow) { /** * When splitting touch events, the downTime should be adjusted such that the downTime corresponds * to the event time of the first ACTION_DOWN sent to the new window. - * If a new window that does not support split appears on the screen and gets touched with the - * second finger, it should not get any events because it doesn't want split touches. At the same - * time, the first window should not get the pointer_down event because it supports split touches - * (and the touch occurred outside of the bounds of window1). + * If a new window appears on the screen and gets touched with the + * second finger, it should get the new event. At the same + * time, the first window should not get the pointer_down event because + * the touch occurred outside of its bounds. */ -TEST_F(InputDispatcherTest, SplitTouchesDropsEventForNonSplittableSecondWindow) { - SCOPED_FLAG_OVERRIDE(split_all_touches, false); +TEST_F(InputDispatcherTest, SplitTouchesWhenWindowIsAdded) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window1 = sp<FakeWindowHandle>::make(application, mDispatcher, "Window1", DISPLAY_ID); @@ -4345,16 +4368,16 @@ TEST_F(InputDispatcherTest, SplitTouchesDropsEventForNonSplittableSecondWindow) AllOf(WithMotionAction(ACTION_DOWN), WithDownTime(downArgs.downTime))); // Second window is added - window2->setPreventSplitting(true); mDispatcher->onWindowInfosChanged({{*window1->getInfo(), *window2->getInfo()}, {}, 0, 0}); - // Now touch down on the window with another pointer + // Now touch down on the new window with another pointer mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) .pointer(PointerBuilder(1, ToolType::FINGER).x(150).y(50)) .downTime(downArgs.downTime) .build()); - // Event is dropped because window2 doesn't support split touch, and window1 does. + window1->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithPointerCount(1))); + window2->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); // Complete the gesture mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN) @@ -4365,6 +4388,8 @@ TEST_F(InputDispatcherTest, SplitTouchesDropsEventForNonSplittableSecondWindow) // A redundant MOVE event is generated that doesn't carry any new information window1->consumeMotionEvent( AllOf(WithMotionAction(ACTION_MOVE), WithDownTime(downArgs.downTime))); + window2->consumeMotionEvent(WithMotionAction(ACTION_UP)); + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) .downTime(downArgs.downTime) @@ -4584,22 +4609,20 @@ TEST_F(InputDispatcherTest, TwoPointersDownMouseClick) { * A spy window sits above a window with NO_INPUT_CHANNEL. Ensure that the spy receives events even * though the window underneath should not get any events. */ -TEST_F(InputDispatcherTest, NonSplittableSpyAboveNoInputChannelWindowSinglePointer) { +TEST_F(InputDispatcherTest, SpyAboveNoInputChannelWindowSinglePointer) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> spyWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Spy", ui::LogicalDisplayId::DEFAULT); spyWindow->setFrame(Rect(0, 0, 100, 100)); spyWindow->setTrustedOverlay(true); - spyWindow->setPreventSplitting(true); spyWindow->setSpy(true); - // Another window below spy that has both NO_INPUT_CHANNEL and PREVENT_SPLITTING + // Another window below spy that has NO_INPUT_CHANNEL sp<FakeWindowHandle> inputSinkWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Input sink below spy", ui::LogicalDisplayId::DEFAULT); inputSinkWindow->setFrame(Rect(0, 0, 100, 100)); inputSinkWindow->setTrustedOverlay(true); - inputSinkWindow->setPreventSplitting(true); inputSinkWindow->setNoInputChannel(true); mDispatcher->onWindowInfosChanged( @@ -4624,22 +4647,20 @@ TEST_F(InputDispatcherTest, NonSplittableSpyAboveNoInputChannelWindowSinglePoint * though the window underneath should not get any events. * Same test as above, but with two pointers touching instead of one. */ -TEST_F(InputDispatcherTest, NonSplittableSpyAboveNoInputChannelWindowTwoPointers) { +TEST_F(InputDispatcherTest, SpyAboveNoInputChannelWindowTwoPointers) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> spyWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Spy", ui::LogicalDisplayId::DEFAULT); spyWindow->setFrame(Rect(0, 0, 100, 100)); spyWindow->setTrustedOverlay(true); - spyWindow->setPreventSplitting(true); spyWindow->setSpy(true); - // Another window below spy that would have both NO_INPUT_CHANNEL and PREVENT_SPLITTING + // Another window below spy that would have NO_INPUT_CHANNEL sp<FakeWindowHandle> inputSinkWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Input sink below spy", ui::LogicalDisplayId::DEFAULT); inputSinkWindow->setFrame(Rect(0, 0, 100, 100)); inputSinkWindow->setTrustedOverlay(true); - inputSinkWindow->setPreventSplitting(true); inputSinkWindow->setNoInputChannel(true); mDispatcher->onWindowInfosChanged( @@ -4671,15 +4692,10 @@ TEST_F(InputDispatcherTest, NonSplittableSpyAboveNoInputChannelWindowTwoPointers inputSinkWindow->assertNoEvents(); } -/** Check the behaviour for cases where input sink prevents or doesn't prevent splitting. */ -class SpyThatPreventsSplittingWithApplicationFixture : public InputDispatcherTest, - public ::testing::WithParamInterface<bool> { -}; - /** * Three windows: * - An application window (app window) - * - A spy window that does not overlap the app window. Has PREVENT_SPLITTING flag + * - A spy window that does not overlap the app window. * - A window below the spy that has NO_INPUT_CHANNEL (call it 'inputSink') * * The spy window is side-by-side with the app window. The inputSink is below the spy. @@ -4687,34 +4703,31 @@ class SpyThatPreventsSplittingWithApplicationFixture : public InputDispatcherTes * Only the SPY window should get the DOWN event. * The spy pilfers after receiving the first DOWN event. * Next, we touch the app window. - * The spy should receive POINTER_DOWN(1) (since spy is preventing splits). - * Also, since the spy is already pilfering the first pointer, it will be sent the remaining new - * pointers automatically, as well. + * The spy should not receive POINTER_DOWN(1) (since the pointer is outside of the spy). * Next, the first pointer (from the spy) is lifted. - * Spy should get POINTER_UP(0). + * Spy should get ACTION_UP. * This event should not go to the app because the app never received this pointer to begin with. - * Now, lift the remaining pointer and check that the spy receives UP event. + * However, due to the current implementation, this would still cause an ACTION_MOVE event in the + * app. + * Now, lift the remaining pointer and check that the app receives UP event. * - * Finally, send a new ACTION_DOWN event to the spy and check that it's received. + * Finally, send a new ACTION_DOWN event to the spy and check that it gets received. * This test attempts to reproduce a crash in the dispatcher. */ -TEST_P(SpyThatPreventsSplittingWithApplicationFixture, SpyThatPreventsSplittingWithApplication) { - SCOPED_FLAG_OVERRIDE(split_all_touches, false); +TEST_F(InputDispatcherTest, SpyThatPilfersAfterFirstPointerWithTwoOtherWindows) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> spyWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Spy", ui::LogicalDisplayId::DEFAULT); spyWindow->setFrame(Rect(100, 100, 200, 200)); spyWindow->setTrustedOverlay(true); - spyWindow->setPreventSplitting(true); spyWindow->setSpy(true); - // Another window below spy that has both NO_INPUT_CHANNEL and PREVENT_SPLITTING + // Another window below spy that has NO_INPUT_CHANNEL sp<FakeWindowHandle> inputSinkWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Input sink below spy", ui::LogicalDisplayId::DEFAULT); inputSinkWindow->setFrame(Rect(100, 100, 200, 200)); // directly below the spy inputSinkWindow->setTrustedOverlay(true); - inputSinkWindow->setPreventSplitting(GetParam()); inputSinkWindow->setNoInputChannel(true); sp<FakeWindowHandle> appWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "App", @@ -4736,16 +4749,15 @@ TEST_P(SpyThatPreventsSplittingWithApplicationFixture, SpyThatPreventsSplittingW mDispatcher->pilferPointers(spyWindow->getToken()); - // Second finger lands in the app, and goes to the spy window. It doesn't go to the app because - // the spy is already pilfering the first pointer, and this automatically grants the remaining - // new pointers to the spy, as well. + // Second finger lands in the app. It goes to the app as ACTION_DOWN. mDispatcher->notifyMotion( MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(150)) .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50)) .build()); - spyWindow->consumeMotionPointerDown(1, WithPointerCount(2)); + spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithPointerCount(1))); + appWindow->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); // Now lift up the first pointer mDispatcher->notifyMotion( @@ -4753,14 +4765,15 @@ TEST_P(SpyThatPreventsSplittingWithApplicationFixture, SpyThatPreventsSplittingW .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(150)) .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50)) .build()); - spyWindow->consumeMotionPointerUp(0, WithPointerCount(2)); + spyWindow->consumeMotionEvent(WithMotionAction(ACTION_UP)); + appWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithPointerCount(1))); // And lift the remaining pointer! mDispatcher->notifyMotion( MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50)) .build()); - spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithPointerCount(1))); + appWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithPointerCount(1))); // Now send a new DOWN, which should again go to spy. mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) @@ -4772,10 +4785,6 @@ TEST_P(SpyThatPreventsSplittingWithApplicationFixture, SpyThatPreventsSplittingW appWindow->assertNoEvents(); } -// Behaviour should be the same regardless of whether inputSink supports splitting. -INSTANTIATE_TEST_SUITE_P(SpyThatPreventsSplittingWithApplication, - SpyThatPreventsSplittingWithApplicationFixture, testing::Bool()); - TEST_F(InputDispatcherTest, HoverWithSpyWindows) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); @@ -5482,7 +5491,8 @@ TEST_F(InputDispatcherTest, InterceptKeyByPolicy) { generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ui::LogicalDisplayId::DEFAULT); const std::chrono::milliseconds interceptKeyTimeout = 50ms; const nsecs_t injectTime = keyArgs.eventTime; - mFakePolicy->setInterceptKeyTimeout(interceptKeyTimeout); + mFakePolicy->setInterceptKeyBeforeDispatchingResult( + std::chrono::nanoseconds(interceptKeyTimeout).count()); mDispatcher->notifyKey(keyArgs); // The dispatching time should be always greater than or equal to intercept key timeout. window->consumeKeyDown(ui::LogicalDisplayId::DEFAULT); @@ -5510,7 +5520,7 @@ TEST_F(InputDispatcherTest, InterceptKeyIfKeyUp) { // Set a value that's significantly larger than the default consumption timeout. If the // implementation is correct, the actual value doesn't matter; it won't slow down the test. - mFakePolicy->setInterceptKeyTimeout(600ms); + mFakePolicy->setInterceptKeyBeforeDispatchingResult(std::chrono::nanoseconds(600ms).count()); mDispatcher->notifyKey(generateKeyArgs(AKEY_EVENT_ACTION_UP, ui::LogicalDisplayId::DEFAULT)); // Window should receive key event immediately when same key up. window->consumeKeyUp(ui::LogicalDisplayId::DEFAULT); @@ -5729,14 +5739,12 @@ TEST_F(InputDispatcherTest, OnWindowInfosChanged_RemoveAllWindowsOnDisplay) { window->assertNoEvents(); } -TEST_F(InputDispatcherTest, NonSplitTouchableWindowReceivesMultiTouch) { - SCOPED_FLAG_OVERRIDE(split_all_touches, false); +TEST_F(InputDispatcherTest, WindowDoesNotReceiveSecondPointerOutsideOfItsBounds) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Fake Window", ui::LogicalDisplayId::DEFAULT); - // Ensure window is non-split and have some transform. - window->setPreventSplitting(true); + // Ensure window has a non-trivial transform. window->setWindowOffset(20, 40); mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0}); @@ -5744,7 +5752,10 @@ TEST_F(InputDispatcherTest, NonSplitTouchableWindowReceivesMultiTouch) { injectMotionDown(*mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, {50, 50})) << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; - window->consumeMotionDown(ui::LogicalDisplayId::DEFAULT); + window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), + WithCoords(70, // 50 + 20 + 90 // 50 + 40 + ))); const MotionEvent secondFingerDownEvent = MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) @@ -5753,45 +5764,32 @@ TEST_F(InputDispatcherTest, NonSplitTouchableWindowReceivesMultiTouch) { .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(50)) .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(-30).y(-50)) .build(); - ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + ASSERT_EQ(InputEventInjectionResult::FAILED, injectMotionEvent(*mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT, InputEventInjectionSync::WAIT_FOR_RESULT)) - << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; - - std::unique_ptr<MotionEvent> event = window->consumeMotionEvent(); - ASSERT_NE(nullptr, event); - EXPECT_EQ(POINTER_1_DOWN, event->getAction()); - EXPECT_EQ(70, event->getX(0)); // 50 + 20 - EXPECT_EQ(90, event->getY(0)); // 50 + 40 - EXPECT_EQ(-10, event->getX(1)); // -30 + 20 - EXPECT_EQ(-10, event->getY(1)); // -50 + 40 + << "Injection should fail because the second finger is outside of any window on the " + "screen."; } /** - * Two windows: a splittable and a non-splittable. - * The non-splittable window shouldn't receive any "incomplete" gestures. - * Send the first pointer to the splittable window, and then touch the non-splittable window. - * The second pointer should be dropped because the initial window is splittable, so it won't get - * any pointers outside of it, and the second window is non-splittable, so it shouldn't get any - * "incomplete" gestures. + * Two windows. + * Send the first pointer to the left window, and then touch the right window. + * The second pointer should generate an ACTION_DOWN in the right window. */ -TEST_F(InputDispatcherTest, SplittableAndNonSplittableWindows) { - SCOPED_FLAG_OVERRIDE(split_all_touches, false); +TEST_F(InputDispatcherTest, TwoWindowsTwoPointers) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> leftWindow = - sp<FakeWindowHandle>::make(application, mDispatcher, "Left splittable Window", + sp<FakeWindowHandle>::make(application, mDispatcher, "Left Window", ui::LogicalDisplayId::DEFAULT); - leftWindow->setPreventSplitting(false); leftWindow->setFrame(Rect(0, 0, 100, 100)); sp<FakeWindowHandle> rightWindow = - sp<FakeWindowHandle>::make(application, mDispatcher, "Right non-splittable Window", + sp<FakeWindowHandle>::make(application, mDispatcher, "Right Window", ui::LogicalDisplayId::DEFAULT); - rightWindow->setPreventSplitting(true); rightWindow->setFrame(Rect(100, 100, 200, 200)); mDispatcher->onWindowInfosChanged( {{*leftWindow->getInfo(), *rightWindow->getInfo()}, {}, 0, 0}); - // Touch down on left, splittable window + // Touch down on left window mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) .build()); @@ -5802,8 +5800,8 @@ TEST_F(InputDispatcherTest, SplittableAndNonSplittableWindows) { .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(50)) .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(150).y(150)) .build()); - leftWindow->assertNoEvents(); - rightWindow->assertNoEvents(); + leftWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE)); + rightWindow->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); } /** @@ -5826,7 +5824,6 @@ TEST_F(InputDispatcherTest, WallpaperWindowWhenSlipperyAndMultiWindowMultiTouch) sp<FakeWindowHandle>::make(application1, mDispatcher, "wallpaper", ui::LogicalDisplayId::DEFAULT); wallpaper->setIsWallpaper(true); - wallpaper->setPreventSplitting(true); wallpaper->setTouchable(false); sp<FakeWindowHandle> leftWindow = sp<FakeWindowHandle>::make(application2, mDispatcher, "Left", @@ -5960,7 +5957,6 @@ TEST_F(InputDispatcherTest, WallpaperWindowWhenSlipperyAndMultiWindowMultiTouch_ sp<FakeWindowHandle>::make(application1, mDispatcher, "wallpaper", ui::LogicalDisplayId::DEFAULT); wallpaper->setIsWallpaper(true); - wallpaper->setPreventSplitting(true); wallpaper->setTouchable(false); sp<FakeWindowHandle> leftWindow = sp<FakeWindowHandle>::make(application2, mDispatcher, "Left", @@ -6074,20 +6070,18 @@ TEST_F(InputDispatcherTest, WallpaperWindowWhenSlipperyAndMultiWindowMultiTouch_ } /** - * Two windows: left and right. The left window has PREVENT_SPLITTING input config. Device A sends a - * down event to the right window. Device B sends a down event to the left window, and then a - * POINTER_DOWN event to the right window. However, since the left window prevents splitting, the - * POINTER_DOWN event should only go to the left window, and not to the right window. + * Two windows: left and right. Device A sends a DOWN event to the right window. Device B sends a + * DOWN event to the left window, and then a POINTER_DOWN event outside of all windows. + * The POINTER_DOWN event should be dropped. * This test attempts to reproduce a crash. */ -TEST_F(InputDispatcherTest, MultiDeviceTwoWindowsPreventSplitting) { - SCOPED_FLAG_OVERRIDE(split_all_touches, false); +TEST_F(InputDispatcherTest, MultiDeviceTwoWindowsTwoPointers) { + SCOPED_FLAG_OVERRIDE(enable_multi_device_same_window_stream, true); std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> leftWindow = - sp<FakeWindowHandle>::make(application, mDispatcher, "Left window (prevent splitting)", + sp<FakeWindowHandle>::make(application, mDispatcher, "Left window", ui::LogicalDisplayId::DEFAULT); leftWindow->setFrame(Rect(0, 0, 100, 100)); - leftWindow->setPreventSplitting(true); sp<FakeWindowHandle> rightWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Right window", @@ -6111,14 +6105,14 @@ TEST_F(InputDispatcherTest, MultiDeviceTwoWindowsPreventSplitting) { .deviceId(deviceB) .build()); leftWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceB))); - // Send a second pointer from device B to the right window. It shouldn't go to the right window - // because the left window prevents splitting. + + // Send a second pointer from device B to an area outside of all windows. mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) .deviceId(deviceB) .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120)) .build()); - leftWindow->consumeMotionPointerDown(1, WithDeviceId(deviceB)); + // This is dropped because there's no touchable window at the location (120, 120) // Finish the gesture for both devices mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN) @@ -6126,7 +6120,8 @@ TEST_F(InputDispatcherTest, MultiDeviceTwoWindowsPreventSplitting) { .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120)) .build()); - leftWindow->consumeMotionPointerUp(1, WithDeviceId(deviceB)); + leftWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), WithPointerId(0, 0))); + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) .deviceId(deviceB) @@ -6505,19 +6500,47 @@ TEST_F(InputDispatcherDisplayProjectionTest, WindowGetsEventsInCorrectCoordinate ui::LogicalDisplayId::DEFAULT, {PointF{150, 220}})); firstWindow->assertNoEvents(); - std::unique_ptr<MotionEvent> event = secondWindow->consumeMotionEvent(); - ASSERT_NE(nullptr, event); - EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, event->getAction()); + secondWindow->consumeMotionEvent( + AllOf(WithMotionAction(ACTION_DOWN), + // Ensure that the events from the "getRaw" API are in logical display + // coordinates, which has an x-scale of 2 and y-scale of 4. + WithRawCoords(300, 880), + // Ensure that the x and y values are in the window's coordinate space. + // The left-top of the second window is at (100, 200) in display space, which is + // (200, 800) in the logical display space. This will be the origin of the window + // space. + WithCoords(100, 80))); +} - // Ensure that the events from the "getRaw" API are in logical display coordinates. - EXPECT_EQ(300, event->getRawX(0)); - EXPECT_EQ(880, event->getRawY(0)); +TEST_F(InputDispatcherDisplayProjectionTest, UseCloneLayerStackTransformForRawCoordinates) { + SCOPED_FLAG_OVERRIDE(use_cloned_screen_coordinates_as_raw, true); - // Ensure that the x and y values are in the window's coordinate space. - // The left-top of the second window is at (100, 200) in display space, which is (200, 800) in - // the logical display space. This will be the origin of the window space. - EXPECT_EQ(100, event->getX(0)); - EXPECT_EQ(80, event->getY(0)); + auto [firstWindow, secondWindow] = setupScaledDisplayScenario(); + + const std::array<float, 9> matrix = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 0.0, 0.0, 1.0}; + ui::Transform secondDisplayTransform; + secondDisplayTransform.set(matrix); + addDisplayInfo(SECOND_DISPLAY_ID, secondDisplayTransform); + + // When a clone layer stack transform is provided for a window, we should use that as the + // "display transform" for input going to that window. + sp<FakeWindowHandle> secondWindowClone = secondWindow->clone(SECOND_DISPLAY_ID); + secondWindowClone->editInfo()->cloneLayerStackTransform = ui::Transform(); + secondWindowClone->editInfo()->cloneLayerStackTransform->set(0.5, 0, 0, 0.25); + addWindow(secondWindowClone); + + // Touch down on the clone window, and ensure its raw coordinates use + // the clone layer stack transform. + mDispatcher->notifyMotion(generateMotionArgs(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, + SECOND_DISPLAY_ID, {PointF{150, 220}})); + secondWindowClone->consumeMotionEvent( + AllOf(WithMotionAction(ACTION_DOWN), + // Ensure the x and y coordinates are in the window's coordinate space. + // See previous test case for calculation. + WithCoords(100, 80), + // Ensure the "getRaw" API uses the clone layer stack transform when it is + // provided for the window. It has an x-scale of 0.5 and y-scale of 0.25. + WithRawCoords(75, 55))); } TEST_F(InputDispatcherDisplayProjectionTest, CancelMotionWithCorrectCoordinates) { @@ -6953,7 +6976,7 @@ TEST_P(TransferTouchFixture, TransferTouch_MultipleWindowsWithSpy) { AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); } -TEST_P(TransferTouchFixture, TransferTouch_TwoPointersNonSplitTouch) { +TEST_P(TransferTouchFixture, TransferTouch_TwoPointers) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); PointF touchPoint = {10, 10}; @@ -6962,11 +6985,9 @@ TEST_P(TransferTouchFixture, TransferTouch_TwoPointersNonSplitTouch) { sp<FakeWindowHandle> firstWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "First Window", ui::LogicalDisplayId::DEFAULT); - firstWindow->setPreventSplitting(true); sp<FakeWindowHandle> secondWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Second Window", ui::LogicalDisplayId::DEFAULT); - secondWindow->setPreventSplitting(true); // Add the windows to the dispatcher mDispatcher->onWindowInfosChanged( @@ -7418,7 +7439,8 @@ TEST_F(InputDispatcherTest, FocusedWindow_DoesNotReceivePolicyConsumedKey) { window->consumeFocusEvent(true); - mFakePolicy->setConsumeKeyBeforeDispatching(true); + mFakePolicy->setInterceptKeyBeforeDispatchingResult( + inputdispatcher::KeyEntry::InterceptKeyResult::SKIP); mDispatcher->notifyKey( KeyArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_KEYBOARD).keyCode(AKEYCODE_A).build()); @@ -7444,7 +7466,8 @@ TEST_F(InputDispatcherTest, FocusedWindow_PolicyConsumedKeyIgnoresDisableUserAct window->consumeFocusEvent(true); - mFakePolicy->setConsumeKeyBeforeDispatching(true); + mFakePolicy->setInterceptKeyBeforeDispatchingResult( + inputdispatcher::KeyEntry::InterceptKeyResult::SKIP); mDispatcher->notifyKey( KeyArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_KEYBOARD).keyCode(AKEYCODE_A).build()); @@ -8081,6 +8104,17 @@ TEST_F(InputDispatcherTest, VerifyInputEvent_KeyEvent) { ASSERT_EQ(keyArgs.scanCode, verifiedKey.scanCode); ASSERT_EQ(keyArgs.metaState, verifiedKey.metaState); ASSERT_EQ(0, verifiedKey.repeatCount); + + // InputEvent and subclasses don't have a virtual destructor and only + // InputEvent's destructor gets called when `verified` goes out of scope, + // even if `verifyInputEvent` returns an object of a subclass. To fix this, + // we should either consider using std::variant in some way, or introduce an + // intermediate POD data structure that we will put the data into just prior + // to signing. Adding virtual functions to these classes is undesirable as + // the bytes in these objects are getting signed. As a temporary fix, cast + // the pointer to the correct class (which is statically known) before + // destruction. + delete (VerifiedKeyEvent*)verified.release(); } TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) { @@ -8128,6 +8162,10 @@ TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) { EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos); EXPECT_EQ(motionArgs.metaState, verifiedMotion.metaState); EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState); + + // Cast to the correct type before destruction. See explanation at the end + // of the VerifyInputEvent_KeyEvent test. + delete (VerifiedMotionEvent*)verified.release(); } /** @@ -8823,12 +8861,10 @@ TEST_F(InputDispatcherTest, HoverEnterExitSynthesisUsesNewEventId) { } /** - * When a device reports a DOWN event, which lands in a window that supports splits, and then the - * device then reports a POINTER_DOWN, which lands in the location of a non-existing window, then - * the previous window should receive this event and not be dropped. + * First finger lands into a window, and then the second finger lands in the location of a + * non-existent window. The second finger should be dropped. */ TEST_F(InputDispatcherMultiDeviceTest, SingleDevicePointerDownEventRetentionWithoutWindowTarget) { - SCOPED_FLAG_OVERRIDE(split_all_touches, false); std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window", ui::LogicalDisplayId::DEFAULT); @@ -8846,13 +8882,13 @@ TEST_F(InputDispatcherMultiDeviceTest, SingleDevicePointerDownEventRetentionWith .pointer(PointerBuilder(1, ToolType::FINGER).x(200).y(200)) .build()); - window->consumeMotionEvent(AllOf(WithMotionAction(POINTER_1_DOWN))); + window->assertNoEvents(); } /** * When deviceA reports a DOWN event, which lands in a window that supports splits, and then deviceB * also reports a DOWN event, which lands in the location of a non-existing window, then the - * previous window should receive deviceB's event and it should be dropped. + * previous window should not receive deviceB's event and it should be dropped. */ TEST_F(InputDispatcherMultiDeviceTest, SecondDeviceDownEventDroppedWithoutWindowTarget) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); @@ -9274,6 +9310,24 @@ TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterUp) { mWindow->assertNoEvents(); } +TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterFocusedWindowChanged) { + sp<FakeWindowHandle> anotherWindow = + sp<FakeWindowHandle>::make(mApp, mDispatcher, "AnotherWindow", + ui::LogicalDisplayId::DEFAULT); + anotherWindow->setFocusable(true); + mDispatcher->onWindowInfosChanged({{*mWindow->getInfo(), *anotherWindow->getInfo()}, {}, 0, 0}); + + sendAndConsumeKeyDown(/*deviceId=*/1); + expectKeyRepeatOnce(/*repeatCount=*/1); + expectKeyRepeatOnce(/*repeatCount=*/2); + setFocusedWindow(anotherWindow); + anotherWindow->consumeFocusEvent(true); + + // Window should receive key up event with cancel. + mWindow->consumeKeyUp(ui::LogicalDisplayId::DEFAULT, AKEY_EVENT_FLAG_CANCELED); + anotherWindow->assertNoEvents(); +} + TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_KeyRepeatAfterStaleDeviceKeyUp) { sendAndConsumeKeyDown(/*deviceId=*/1); expectKeyRepeatOnce(/*repeatCount=*/1); @@ -9872,6 +9926,15 @@ TEST_F(InputFilterInjectionPolicyTest, AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT); } +TEST_F(InputFilterInjectionPolicyTest, + MotionEventsInjectedFromAccessibilityTool_HaveAccessibilityFlags) { + testInjectedMotion(POLICY_FLAG_FILTERED | POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY | + POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL, + /*injectedDeviceId=*/3, /*resolvedDeviceId=*/3, + AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT | + AMOTION_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL); +} + TEST_F(InputFilterInjectionPolicyTest, RegularInjectedEvents_ReceiveVirtualDeviceId) { testInjectedKey(/*policyFlags=*/0, /*injectedDeviceId=*/3, /*resolvedDeviceId=*/VIRTUAL_KEYBOARD_ID, /*flags=*/0); @@ -9882,6 +9945,9 @@ protected: virtual void SetUp() override { InputDispatcherTest::SetUp(); + // Use current time as start time otherwise events may be dropped due to being stale. + mGestureStartTime = std::chrono::nanoseconds(systemTime(SYSTEM_TIME_MONOTONIC)); + std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); application->setDispatchingTimeout(100ms); @@ -9899,18 +9965,23 @@ protected: mWindow->consumeFocusEvent(true); } - void notifyAndConsumeMotion(int32_t action, uint32_t source, ui::LogicalDisplayId displayId, - nsecs_t eventTime) { - mDispatcher->notifyMotion(MotionArgsBuilder(action, source) - .displayId(displayId) - .eventTime(eventTime) - .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) - .build()); + NotifyMotionArgs notifyAndConsumeMotion(int32_t action, uint32_t source, + ui::LogicalDisplayId displayId, + std::chrono::nanoseconds timeDelay) { + const NotifyMotionArgs motionArgs = + MotionArgsBuilder(action, source) + .displayId(displayId) + .eventTime((mGestureStartTime + timeDelay).count()) + .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50)) + .build(); + mDispatcher->notifyMotion(motionArgs); mWindow->consumeMotionEvent(WithMotionAction(action)); + return motionArgs; } private: sp<FakeWindowHandle> mWindow; + std::chrono::nanoseconds mGestureStartTime; }; TEST_F_WITH_FLAGS( @@ -9920,55 +9991,55 @@ TEST_F_WITH_FLAGS( mDispatcher->setMinTimeBetweenUserActivityPokes(50ms); // First event of type TOUCH. Should poke. - notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, - milliseconds_to_nanoseconds(50)); + NotifyMotionArgs motionArgs = + notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, + ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(50)); mFakePolicy->assertUserActivityPoked( - {{milliseconds_to_nanoseconds(50), USER_ACTIVITY_EVENT_TOUCH, - ui::LogicalDisplayId::DEFAULT}}); + {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}}); // 80ns > 50ns has passed since previous TOUCH event. Should poke. - notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, - milliseconds_to_nanoseconds(130)); + motionArgs = + notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, + ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(130)); mFakePolicy->assertUserActivityPoked( - {{milliseconds_to_nanoseconds(130), USER_ACTIVITY_EVENT_TOUCH, - ui::LogicalDisplayId::DEFAULT}}); + {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}}); // First event of type OTHER. Should poke (despite being within 50ns of previous TOUCH event). - notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER, - ui::LogicalDisplayId::DEFAULT, milliseconds_to_nanoseconds(135)); + motionArgs = + notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER, + ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(135)); mFakePolicy->assertUserActivityPoked( - {{milliseconds_to_nanoseconds(135), USER_ACTIVITY_EVENT_OTHER, - ui::LogicalDisplayId::DEFAULT}}); + {{motionArgs.eventTime, USER_ACTIVITY_EVENT_OTHER, ui::LogicalDisplayId::DEFAULT}}); // Within 50ns of previous TOUCH event. Should NOT poke. notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, - milliseconds_to_nanoseconds(140)); + std::chrono::milliseconds(140)); mFakePolicy->assertUserActivityNotPoked(); // Within 50ns of previous OTHER event. Should NOT poke. notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER, - ui::LogicalDisplayId::DEFAULT, milliseconds_to_nanoseconds(150)); + ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(150)); mFakePolicy->assertUserActivityNotPoked(); // Within 50ns of previous TOUCH event (which was at time 130). Should NOT poke. // Note that STYLUS is mapped to TOUCH user activity, since it's a pointer-type source. notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_STYLUS, ui::LogicalDisplayId::DEFAULT, - milliseconds_to_nanoseconds(160)); + std::chrono::milliseconds(160)); mFakePolicy->assertUserActivityNotPoked(); // 65ns > 50ns has passed since previous OTHER event. Should poke. - notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER, - ui::LogicalDisplayId::DEFAULT, milliseconds_to_nanoseconds(200)); + motionArgs = + notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER, + ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(200)); mFakePolicy->assertUserActivityPoked( - {{milliseconds_to_nanoseconds(200), USER_ACTIVITY_EVENT_OTHER, - ui::LogicalDisplayId::DEFAULT}}); + {{motionArgs.eventTime, USER_ACTIVITY_EVENT_OTHER, ui::LogicalDisplayId::DEFAULT}}); // 170ns > 50ns has passed since previous TOUCH event. Should poke. - notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_STYLUS, ui::LogicalDisplayId::DEFAULT, - milliseconds_to_nanoseconds(300)); + motionArgs = + notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_STYLUS, ui::LogicalDisplayId::DEFAULT, + std::chrono::milliseconds(300)); mFakePolicy->assertUserActivityPoked( - {{milliseconds_to_nanoseconds(300), USER_ACTIVITY_EVENT_TOUCH, - ui::LogicalDisplayId::DEFAULT}}); + {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}}); // Assert that there's no more user activity poke event. mFakePolicy->assertUserActivityNotPoked(); @@ -9978,21 +10049,21 @@ TEST_F_WITH_FLAGS( InputDispatcherUserActivityPokeTests, DefaultMinPokeTimeOf100MsUsed, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags, rate_limit_user_activity_poke_in_dispatcher))) { - notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, - milliseconds_to_nanoseconds(200)); + NotifyMotionArgs motionArgs = + notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, + ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(200)); mFakePolicy->assertUserActivityPoked( - {{milliseconds_to_nanoseconds(200), USER_ACTIVITY_EVENT_TOUCH, - ui::LogicalDisplayId::DEFAULT}}); + {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}}); notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, - milliseconds_to_nanoseconds(280)); + std::chrono::milliseconds(280)); mFakePolicy->assertUserActivityNotPoked(); - notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, - milliseconds_to_nanoseconds(340)); + motionArgs = + notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, + ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(340)); mFakePolicy->assertUserActivityPoked( - {{milliseconds_to_nanoseconds(340), USER_ACTIVITY_EVENT_TOUCH, - ui::LogicalDisplayId::DEFAULT}}); + {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}}); } TEST_F_WITH_FLAGS( @@ -10002,11 +10073,11 @@ TEST_F_WITH_FLAGS( mDispatcher->setMinTimeBetweenUserActivityPokes(0ms); notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, - 20); + std::chrono::milliseconds(20)); mFakePolicy->assertUserActivityPoked(); notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, - 30); + std::chrono::milliseconds(30)); mFakePolicy->assertUserActivityPoked(); } @@ -12324,6 +12395,11 @@ protected: sp<FakeWindowHandle> mSecondWindow; sp<FakeWindowHandle> mDragWindow; sp<FakeWindowHandle> mSpyWindow; + + std::vector<gui::DisplayInfo> mDisplayInfos; + + std::shared_ptr<FakeApplicationHandle> mSecondApplication; + sp<FakeWindowHandle> mWindowOnSecondDisplay; // Mouse would force no-split, set the id as non-zero to verify if drag state could track it. static constexpr int32_t MOUSE_POINTER_ID = 1; @@ -12344,85 +12420,141 @@ protected: mSpyWindow->setTrustedOverlay(true); mSpyWindow->setFrame(Rect(0, 0, 200, 100)); + mSecondApplication = std::make_shared<FakeApplicationHandle>(); + mWindowOnSecondDisplay = + sp<FakeWindowHandle>::make(mSecondApplication, mDispatcher, + "TestWindowOnSecondDisplay", SECOND_DISPLAY_ID); + mWindowOnSecondDisplay->setFrame({0, 0, 100, 100}); + mDispatcher->setFocusedApplication(ui::LogicalDisplayId::DEFAULT, mApp); mDispatcher->onWindowInfosChanged( - {{*mSpyWindow->getInfo(), *mWindow->getInfo(), *mSecondWindow->getInfo()}, - {}, + {{*mSpyWindow->getInfo(), *mWindow->getInfo(), *mSecondWindow->getInfo(), + *mWindowOnSecondDisplay->getInfo()}, + mDisplayInfos, 0, 0}); } - void injectDown(int fromSource = AINPUT_SOURCE_TOUCHSCREEN) { + void injectDown(int fromSource = AINPUT_SOURCE_TOUCHSCREEN, + ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT) { + bool consumeButtonPress = false; + const PointF location = + displayId == ui::LogicalDisplayId::DEFAULT ? PointF(50, 50) : PointF(50, 450); switch (fromSource) { - case AINPUT_SOURCE_TOUCHSCREEN: + case AINPUT_SOURCE_TOUCHSCREEN: { ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, - injectMotionDown(*mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, - ui::LogicalDisplayId::DEFAULT, {50, 50})) + injectMotionDown(*mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, displayId, + location)) << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; break; - case AINPUT_SOURCE_STYLUS: + } + case AINPUT_SOURCE_STYLUS: { + PointerBuilder pointer = + PointerBuilder(0, ToolType::STYLUS).x(location.x).y(location.y); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_STYLUS) .buttonState( AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) - .pointer(PointerBuilder(0, ToolType::STYLUS) - .x(50) - .y(50)) + .pointer(pointer) .build())); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(*mDispatcher, + MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS, + AINPUT_SOURCE_STYLUS) + .actionButton( + AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) + .buttonState( + AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) + .pointer(pointer) + .build())); + consumeButtonPress = true; break; - case AINPUT_SOURCE_MOUSE: + } + case AINPUT_SOURCE_MOUSE: { + PointerBuilder pointer = PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE) + .x(location.x) + .y(location.y); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE) + .displayId(displayId) .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) - .pointer(PointerBuilder(MOUSE_POINTER_ID, - ToolType::MOUSE) - .x(50) - .y(50)) + .pointer(pointer) .build())); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(*mDispatcher, + MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS, + AINPUT_SOURCE_MOUSE) + .displayId(displayId) + .actionButton(AMOTION_EVENT_BUTTON_PRIMARY) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(pointer) + .build())); + consumeButtonPress = true; break; - default: + } + default: { FAIL() << "Source " << fromSource << " doesn't support drag and drop"; + } } // Window should receive motion event. - mWindow->consumeMotionDown(ui::LogicalDisplayId::DEFAULT); - // Spy window should also receive motion event - mSpyWindow->consumeMotionDown(ui::LogicalDisplayId::DEFAULT); + sp<FakeWindowHandle>& targetWindow = + displayId == ui::LogicalDisplayId::DEFAULT ? mWindow : mWindowOnSecondDisplay; + targetWindow->consumeMotionDown(displayId); + if (consumeButtonPress) { + targetWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS)); + } + + // Spy window should also receive motion event if event is on the same display. + if (displayId == ui::LogicalDisplayId::DEFAULT) { + mSpyWindow->consumeMotionDown(ui::LogicalDisplayId::DEFAULT); + } } // Start performing drag, we will create a drag window and transfer touch to it. // @param sendDown : if true, send a motion down on first window before perform drag and drop. // Returns true on success. - bool startDrag(bool sendDown = true, int fromSource = AINPUT_SOURCE_TOUCHSCREEN) { + bool startDrag(bool sendDown = true, int fromSource = AINPUT_SOURCE_TOUCHSCREEN, + ui::LogicalDisplayId dragStartDisplay = ui::LogicalDisplayId::DEFAULT) { if (sendDown) { - injectDown(fromSource); + injectDown(fromSource, dragStartDisplay); } // The drag window covers the entire display - mDragWindow = sp<FakeWindowHandle>::make(mApp, mDispatcher, "DragWindow", - ui::LogicalDisplayId::DEFAULT); + mDragWindow = sp<FakeWindowHandle>::make(mApp, mDispatcher, "DragWindow", dragStartDisplay); mDragWindow->setTouchableRegion(Region{{0, 0, 0, 0}}); - mDispatcher->onWindowInfosChanged({{*mDragWindow->getInfo(), *mSpyWindow->getInfo(), - *mWindow->getInfo(), *mSecondWindow->getInfo()}, - {}, - 0, - 0}); + mDispatcher->onWindowInfosChanged( + {{*mDragWindow->getInfo(), *mSpyWindow->getInfo(), *mWindow->getInfo(), + *mSecondWindow->getInfo(), *mWindowOnSecondDisplay->getInfo()}, + mDisplayInfos, + 0, + 0}); + + sp<FakeWindowHandle>& targetWindow = dragStartDisplay == ui::LogicalDisplayId::DEFAULT + ? mWindow + : mWindowOnSecondDisplay; // Transfer touch focus to the drag window bool transferred = - mDispatcher->transferTouchGesture(mWindow->getToken(), mDragWindow->getToken(), + mDispatcher->transferTouchGesture(targetWindow->getToken(), mDragWindow->getToken(), /*isDragDrop=*/true); if (transferred) { - mWindow->consumeMotionCancel(); - mDragWindow->consumeMotionDown(ui::LogicalDisplayId::DEFAULT, - AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); + targetWindow->consumeMotionCancel(dragStartDisplay); + mDragWindow->consumeMotionDown(dragStartDisplay, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); } return transferred; } + + void addDisplay(ui::LogicalDisplayId displayId, ui::Transform transform) { + gui::DisplayInfo displayInfo; + displayInfo.displayId = displayId; + displayInfo.transform = transform; + mDisplayInfos.push_back(displayInfo); + } }; TEST_F(InputDispatcherDragTests, DragEnterAndDragExit) { @@ -12589,6 +12721,16 @@ TEST_F(InputDispatcherDragTests, StylusDragAndDrop) { // Move to another window and release button, expect to drop item. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, + MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE, + AINPUT_SOURCE_STYLUS) + .actionButton(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) + .buttonState(0) + .pointer(PointerBuilder(0, ToolType::STYLUS).x(150).y(50)) + .build())) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + mDragWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE)); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(*mDispatcher, MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_STYLUS) .buttonState(0) .pointer(PointerBuilder(0, ToolType::STYLUS).x(150).y(50)) @@ -12653,9 +12795,6 @@ TEST_F(InputDispatcherDragTests, DragAndDropOnInvalidWindow) { } TEST_F(InputDispatcherDragTests, NoDragAndDropWhenMultiFingers) { - // Ensure window could track pointerIds if it didn't support split touch. - mWindow->setPreventSplitting(true); - ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionDown(*mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT, {50, 50})) @@ -12833,6 +12972,18 @@ TEST_F(InputDispatcherDragTests, MouseDragAndDrop) { // drop to another window. ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(*mDispatcher, + MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE, + AINPUT_SOURCE_MOUSE) + .actionButton(AMOTION_EVENT_BUTTON_PRIMARY) + .buttonState(0) + .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE) + .x(150) + .y(50)) + .build())) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + mDragWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE)); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(*mDispatcher, MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE) .buttonState(0) .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE) @@ -13555,14 +13706,10 @@ TEST_F(InputDispatcherSpyWindowTest, ReceivesSecondPointerAsDown) { } /** - * The spy window should not be able to affect whether or not touches are split. Only the foreground - * windows should be allowed to control split touch. + * The spy window should not be able to affect whether or not touches are split. */ TEST_F(InputDispatcherSpyWindowTest, SplitIfNoForegroundWindowTouched) { - // This spy window prevents touch splitting. However, we still expect to split touches - // because a foreground window has not disabled splitting. auto spy = createSpy(); - spy->setPreventSplitting(true); auto window = createForeground(); window->setFrame(Rect(0, 0, 100, 100)); @@ -14903,4 +15050,421 @@ TEST_F(InputDispatcherObscuredFlagTest, StylusHoverObscuredTest) { mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithFlags(0))); } +class TransferOrDontTransferFixture : public InputDispatcherTest, + public ::testing::WithParamInterface<bool> { +public: + void SetUp() override { + InputDispatcherTest::SetUp(); + + std::shared_ptr<FakeApplicationHandle> app = std::make_shared<FakeApplicationHandle>(); + mFromWindow = + sp<FakeWindowHandle>::make(app, mDispatcher, "From", ui::LogicalDisplayId::DEFAULT); + mToWindow = + sp<FakeWindowHandle>::make(app, mDispatcher, "To", ui::LogicalDisplayId::DEFAULT); + + mDispatcher->onWindowInfosChanged( + {{*mFromWindow->getInfo(), *mToWindow->getInfo()}, {}, 0, 0}); + } + +protected: + sp<FakeWindowHandle> mFromWindow; + sp<FakeWindowHandle> mToWindow; +}; + +// Start a touch gesture and then continue hovering the mouse at the same time. +// After the mouse is hovering, invoke transferTouch API. Check the events that +// are received by each of the windows. +TEST_P(TransferOrDontTransferFixture, TouchDownAndMouseHover) { + SCOPED_FLAG_OVERRIDE(enable_multi_device_same_window_stream, false); + + const nsecs_t baseTime = systemTime(SYSTEM_TIME_MONOTONIC); + const int32_t mouseDeviceId = 6; + const int32_t touchDeviceId = 4; + + // Send touch down to the first window + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 10) + .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100)) + .build()); + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); + + // Send touch move to the first window + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 20) + .pointer(PointerBuilder(0, ToolType::FINGER).x(110).y(100)) + .build()); + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE)); + + // Start mouse hover on the first window + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .deviceId(mouseDeviceId) + .downTime(baseTime + 30) + .eventTime(baseTime + 30) + .pointer(PointerBuilder(0, ToolType::MOUSE).x(200).y(200)) + .build()); + + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_CANCEL)); + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER)); + + if (GetParam()) { + // Call transferTouchGesture + const bool transferred = + mDispatcher->transferTouchGesture(mFromWindow->getToken(), mToWindow->getToken()); + ASSERT_TRUE(transferred); + + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT)); + // b/382473355: For some reason, mToWindow also receives HOVER_EXIT first + mToWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT)); + mToWindow->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); + + // Further touch events should be delivered to mTowindow (?) + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 40) + .pointer(PointerBuilder(0, ToolType::FINGER).x(120).y(100)) + .build()); + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 50) + .pointer(PointerBuilder(0, ToolType::FINGER).x(120).y(100)) + .build()); + // b/382473355: Even though the window got ACTION_DOWN, it's no longer receiving the + // remainder of the touch gesture. + + mFromWindow->assertNoEvents(); + mToWindow->assertNoEvents(); + } else { + // Don't call transferTouchGesture + + // Further touch events should be dropped + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 40) + .pointer(PointerBuilder(0, ToolType::FINGER).x(120).y(100)) + .build()); + mFromWindow->assertNoEvents(); + mToWindow->assertNoEvents(); + } +} + +TEST_P(TransferOrDontTransferFixture, MouseAndTouchTransferSimultaneousMultiDevice) { + SCOPED_FLAG_OVERRIDE(enable_multi_device_same_window_stream, true); + + const nsecs_t baseTime = systemTime(SYSTEM_TIME_MONOTONIC); + const int32_t mouseDeviceId = 6; + const int32_t touchDeviceId = 4; + + // Send touch down to the 'From' window + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 10) + .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100)) + .build()); + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); + + // Send touch move to the 'From' window + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 20) + .pointer(PointerBuilder(0, ToolType::FINGER).x(110).y(100)) + .build()); + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE)); + + // Start mouse hover on the 'From' window + mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .deviceId(mouseDeviceId) + .downTime(baseTime + 30) + .eventTime(baseTime + 30) + .pointer(PointerBuilder(0, ToolType::MOUSE).x(200).y(200)) + .build()); + + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER)); + + if (GetParam()) { + // Call transferTouchGesture + const bool transferred = + mDispatcher->transferTouchGesture(mFromWindow->getToken(), mToWindow->getToken()); + ASSERT_TRUE(transferred); + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_CANCEL)); + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT)); + mToWindow->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); + + // Further touch events should be delivered to mToWindow + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 40) + .pointer(PointerBuilder(0, ToolType::FINGER).x(120).y(100)) + .build()); + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 50) + .pointer(PointerBuilder(0, ToolType::FINGER).x(120).y(100)) + .build()); + // b/382473355: Even though the window got ACTION_DOWN, it's receiving another DOWN! + mToWindow->consumeMotionEvent(WithMotionAction(ACTION_DOWN)); + mToWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE)); + mToWindow->consumeMotionEvent(WithMotionAction(ACTION_UP)); + + mFromWindow->assertNoEvents(); + mToWindow->assertNoEvents(); + } else { + // Don't call transferTouchGesture + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .deviceId(touchDeviceId) + .downTime(baseTime + 10) + .eventTime(baseTime + 40) + .pointer(PointerBuilder(0, ToolType::FINGER).x(120).y(100)) + .build()); + mFromWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE)); + mFromWindow->assertNoEvents(); + mToWindow->assertNoEvents(); + } +} + +INSTANTIATE_TEST_SUITE_P(WithAndWithoutTransfer, TransferOrDontTransferFixture, testing::Bool()); + +class InputDispatcherConnectedDisplayTest : public InputDispatcherDragTests { + constexpr static int DENSITY_MEDIUM = 160; + + const DisplayTopologyGraph + mTopology{.primaryDisplayId = DISPLAY_ID, + .graph = {{DISPLAY_ID, + {{SECOND_DISPLAY_ID, DisplayTopologyPosition::TOP, 0.0f}}}, + {SECOND_DISPLAY_ID, + {{DISPLAY_ID, DisplayTopologyPosition::BOTTOM, 0.0f}}}}, + .displaysDensity = {{DISPLAY_ID, DENSITY_MEDIUM}, + {SECOND_DISPLAY_ID, DENSITY_MEDIUM}}}; + +protected: + void SetUp() override { + addDisplay(DISPLAY_ID, ui::Transform()); + addDisplay(SECOND_DISPLAY_ID, + ui::Transform(ui::Transform::ROT_270, /*logicalDisplayWidth=*/ + 500, /*logicalDisplayHeight=*/500)); + + InputDispatcherDragTests::SetUp(); + + mDispatcher->setDisplayTopology(mTopology); + } +}; + +TEST_F(InputDispatcherConnectedDisplayTest, MultiDisplayMouseGesture) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + + // pointer-down + mDispatcher->notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE) + .displayId(DISPLAY_ID) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(0, ToolType::MOUSE).x(60).y(60)) + .build()); + mWindow->consumeMotionEvent( + AllOf(WithMotionAction(ACTION_DOWN), WithDisplayId(DISPLAY_ID), WithRawCoords(60, 60))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS, AINPUT_SOURCE_MOUSE) + .displayId(DISPLAY_ID) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .actionButton(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(0, ToolType::MOUSE).x(60).y(60)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS), + WithDisplayId(DISPLAY_ID), WithRawCoords(60, 60))); + + // pointer-move + mDispatcher->notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE) + .displayId(DISPLAY_ID) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(0, ToolType::MOUSE).x(60).y(60)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), + WithDisplayId(DISPLAY_ID), WithRawCoords(60, 60))); + + // pointer-move with different display + // TODO (b/383092013): by default windows will not be topology aware and receive events as it + // was in the same display. This behaviour has not been implemented yet. + mDispatcher->notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE) + .displayId(SECOND_DISPLAY_ID) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(0, ToolType::MOUSE).x(70).y(70)) + .build()); + // events should be delivered with the second displayId and in corrosponding coordinate space + mWindow->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), + WithDisplayId(SECOND_DISPLAY_ID), WithRawCoords(70, 430))); + + // pointer-up + mDispatcher->notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE, AINPUT_SOURCE_MOUSE) + .displayId(SECOND_DISPLAY_ID) + .buttonState(0) + .actionButton(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(0, ToolType::MOUSE).x(70).y(70)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), + WithDisplayId(SECOND_DISPLAY_ID), WithRawCoords(70, 430))); + + mDispatcher->notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE) + .displayId(SECOND_DISPLAY_ID) + .buttonState(0) + .pointer(PointerBuilder(0, ToolType::MOUSE).x(70).y(70)) + .build()); + mWindow->consumeMotionUp(SECOND_DISPLAY_ID); +} + +TEST_F(InputDispatcherConnectedDisplayTest, MultiDisplayMouseDragAndDropFromPrimaryDisplay) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + + EXPECT_TRUE(startDrag(true, AINPUT_SOURCE_MOUSE)); + // Move on window. + mDispatcher->notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE) + .displayId(DISPLAY_ID) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50)) + .build()); + mDragWindow->consumeMotionMove(DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); + mWindow->consumeDragEvent(false, 50, 50); + mSecondWindow->assertNoEvents(); + mWindowOnSecondDisplay->assertNoEvents(); + + // Move to another window. + mDispatcher->notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE) + .displayId(DISPLAY_ID) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(150).y(50)) + .build()); + mDragWindow->consumeMotionMove(DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); + mWindow->consumeDragEvent(true, 150, 50); + mSecondWindow->consumeDragEvent(false, 50, 50); + mWindowOnSecondDisplay->assertNoEvents(); + + // Move to window on the second display + mDispatcher->notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE) + .displayId(SECOND_DISPLAY_ID) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50)) + .build()); + mDragWindow->consumeMotionMove(SECOND_DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); + mWindow->assertNoEvents(); + mSecondWindow->consumeDragEvent(true, -50, 50); + mWindowOnSecondDisplay->consumeDragEvent(false, 50, 50); + + // drop on the second display + mDispatcher->notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE) + .displayId(SECOND_DISPLAY_ID) + .buttonState(0) + .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50)) + .build()); + mDragWindow->consumeMotionUp(SECOND_DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); + mFakePolicy->assertDropTargetEquals(*mDispatcher, mWindowOnSecondDisplay->getToken()); + mWindow->assertNoEvents(); + mSecondWindow->assertNoEvents(); + mWindowOnSecondDisplay->assertNoEvents(); +} + +TEST_F(InputDispatcherConnectedDisplayTest, MultiDisplayMouseDragAndDropFromNonPrimaryDisplay) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + + EXPECT_TRUE(startDrag(true, AINPUT_SOURCE_MOUSE, SECOND_DISPLAY_ID)); + // Move on window. + mDispatcher->notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE) + .displayId(SECOND_DISPLAY_ID) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50)) + .build()); + mDragWindow->consumeMotionMove(SECOND_DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); + mWindow->assertNoEvents(); + mSecondWindow->assertNoEvents(); + mWindowOnSecondDisplay->consumeDragEvent(false, 50, 50); + + // Move to window on the primary display + mDispatcher->notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE) + .displayId(DISPLAY_ID) + .buttonState(AMOTION_EVENT_BUTTON_PRIMARY) + .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50)) + .build()); + mDragWindow->consumeMotionMove(DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); + mWindow->consumeDragEvent(false, 50, 50); + mSecondWindow->assertNoEvents(); + mWindowOnSecondDisplay->consumeDragEvent(true, 50, 50); + + // drop on the primary display + mDispatcher->notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE) + .displayId(DISPLAY_ID) + .buttonState(0) + .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50)) + .build()); + mDragWindow->consumeMotionUp(DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE); + mFakePolicy->assertDropTargetEquals(*mDispatcher, mWindow->getToken()); + mWindow->assertNoEvents(); + mSecondWindow->assertNoEvents(); + mWindowOnSecondDisplay->assertNoEvents(); +} + +using InputDispatcherConnectedDisplayPointerInWindowTest = InputDispatcherConnectedDisplayTest; + +TEST_F(InputDispatcherConnectedDisplayPointerInWindowTest, MouseOnWindowOnPrimaryDisplay) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/0, ToolType::MOUSE).x(50).y(50)) + .build()); + + mWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER)); + mSpyWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER)); + mWindowOnSecondDisplay->assertNoEvents(); + + ASSERT_TRUE(mDispatcher->isPointerInWindow(mWindow->getToken(), DISPLAY_ID, DEVICE_ID, + /*pointerId=*/0)); + ASSERT_TRUE(mDispatcher->isPointerInWindow(mSpyWindow->getToken(), DISPLAY_ID, DEVICE_ID, + /*pointerId=*/0)); + ASSERT_FALSE(mDispatcher->isPointerInWindow(mWindowOnSecondDisplay->getToken(), + SECOND_DISPLAY_ID, DEVICE_ID, /*pointerId=*/0)); +} + +TEST_F(InputDispatcherConnectedDisplayPointerInWindowTest, MouseOnWindowOnNonPrimaryDisplay) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_MOUSE) + .displayId(SECOND_DISPLAY_ID) + .pointer(PointerBuilder(/*id=*/0, ToolType::MOUSE).x(50).y(50)) + .build()); + + mWindow->assertNoEvents(); + mSpyWindow->assertNoEvents(); + mWindowOnSecondDisplay->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER)); + + ASSERT_FALSE(mDispatcher->isPointerInWindow(mWindow->getToken(), DISPLAY_ID, DEVICE_ID, + /*pointerId=*/0)); + ASSERT_FALSE(mDispatcher->isPointerInWindow(mSpyWindow->getToken(), DISPLAY_ID, DEVICE_ID, + /*pointerId=*/0)); + ASSERT_TRUE(mDispatcher->isPointerInWindow(mWindowOnSecondDisplay->getToken(), + SECOND_DISPLAY_ID, DEVICE_ID, /*pointerId=*/0)); +} + } // namespace android::inputdispatcher diff --git a/services/inputflinger/tests/InputMapperTest.cpp b/services/inputflinger/tests/InputMapperTest.cpp index 8235c90da6..652a6580dc 100644 --- a/services/inputflinger/tests/InputMapperTest.cpp +++ b/services/inputflinger/tests/InputMapperTest.cpp @@ -30,7 +30,7 @@ using testing::NiceMock; using testing::Return; using testing::ReturnRef; -void InputMapperUnitTest::SetUpWithBus(int bus) { +void InputMapperUnitTest::SetUp(int bus, bool isExternal) { mFakePolicy = sp<FakeInputReaderPolicy>::make(); EXPECT_CALL(mMockInputReaderContext, getPolicy()).WillRepeatedly(Return(mFakePolicy.get())); @@ -46,8 +46,9 @@ void InputMapperUnitTest::SetUpWithBus(int bus) { return mPropertyMap; }); - mDevice = std::make_unique<NiceMock<MockInputDevice>>(&mMockInputReaderContext, DEVICE_ID, - /*generation=*/2, mIdentifier); + mDevice = + std::make_unique<NiceMock<MockInputDevice>>(&mMockInputReaderContext, DEVICE_ID, + /*generation=*/2, mIdentifier, isExternal); ON_CALL((*mDevice), getConfiguration).WillByDefault(ReturnRef(mPropertyMap)); mDeviceContext = std::make_unique<InputDeviceContext>(*mDevice, EVENTHUB_ID); } @@ -185,8 +186,10 @@ void InputMapperTest::setDisplayInfoAndReconfigure(ui::LogicalDisplayId displayI const std::string& uniqueId, std::optional<uint8_t> physicalPort, ViewportType viewportType) { - mFakePolicy->addDisplayViewport(displayId, width, height, orientation, /* isActive= */ true, - uniqueId, physicalPort, viewportType); + DisplayViewport viewport = + createViewport(displayId, width, height, orientation, /* isActive= */ true, uniqueId, + physicalPort, viewportType); + mFakePolicy->addDisplayViewport(viewport); configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO); } diff --git a/services/inputflinger/tests/InputMapperTest.h b/services/inputflinger/tests/InputMapperTest.h index 10ef6f1660..edc87a32b0 100644 --- a/services/inputflinger/tests/InputMapperTest.h +++ b/services/inputflinger/tests/InputMapperTest.h @@ -40,8 +40,8 @@ class InputMapperUnitTest : public testing::Test { protected: static constexpr int32_t EVENTHUB_ID = 1; static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000; - virtual void SetUp() override { SetUpWithBus(0); } - virtual void SetUpWithBus(int bus); + virtual void SetUp() override { SetUp(/*bus=*/0, /*isExternal=*/false); } + virtual void SetUp(int bus, bool isExternal); void setupAxis(int axis, bool valid, int32_t min, int32_t max, int32_t resolution, int32_t flat = 0, int32_t fuzz = 0); diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index 0906536e32..43d2378f61 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -28,6 +28,7 @@ #include <MultiTouchInputMapper.h> #include <NotifyArgsBuilders.h> #include <PeripheralController.h> +#include <ScopedFlagOverride.h> #include <SingleTouchInputMapper.h> #include <TestEventMatchers.h> #include <TestInputListener.h> @@ -384,30 +385,29 @@ TEST_F(InputReaderPolicyTest, Viewports_GetCleared) { static const std::string uniqueId = "local:0"; // We didn't add any viewports yet, so there shouldn't be any. - std::optional<DisplayViewport> internalViewport = - mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); - ASSERT_FALSE(internalViewport); + ASSERT_FALSE(mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL)); // Add an internal viewport, then clear it - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, uniqueId, NO_PORT, ViewportType::INTERNAL); - + DisplayViewport internalViewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, uniqueId, NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(internalViewport); // Check matching by uniqueId - internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId); - ASSERT_TRUE(internalViewport); - ASSERT_EQ(ViewportType::INTERNAL, internalViewport->type); + std::optional<DisplayViewport> receivedInternalViewport = + mFakePolicy->getDisplayViewportByUniqueId(uniqueId); + ASSERT_TRUE(receivedInternalViewport.has_value()); + ASSERT_EQ(internalViewport, *receivedInternalViewport); // Check matching by viewport type - internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); - ASSERT_TRUE(internalViewport); - ASSERT_EQ(uniqueId, internalViewport->uniqueId); + receivedInternalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); + ASSERT_TRUE(receivedInternalViewport.has_value()); + ASSERT_EQ(internalViewport, *receivedInternalViewport); mFakePolicy->clearViewports(); + // Make sure nothing is found after clear - internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId); - ASSERT_FALSE(internalViewport); - internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); - ASSERT_FALSE(internalViewport); + ASSERT_FALSE(mFakePolicy->getDisplayViewportByUniqueId(uniqueId)); + ASSERT_FALSE(mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL)); } TEST_F(InputReaderPolicyTest, Viewports_GetByType) { @@ -419,49 +419,49 @@ TEST_F(InputReaderPolicyTest, Viewports_GetByType) { constexpr ui::LogicalDisplayId virtualDisplayId2 = ui::LogicalDisplayId{3}; // Add an internal viewport - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, internalUniqueId, NO_PORT, - ViewportType::INTERNAL); + DisplayViewport internalViewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, internalUniqueId, NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(internalViewport); // Add an external viewport - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, externalUniqueId, NO_PORT, - ViewportType::EXTERNAL); + DisplayViewport externalViewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, externalUniqueId, NO_PORT, ViewportType::EXTERNAL); + mFakePolicy->addDisplayViewport(externalViewport); // Add an virtual viewport - mFakePolicy->addDisplayViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /*isActive=*/true, virtualUniqueId1, NO_PORT, - ViewportType::VIRTUAL); + DisplayViewport virtualViewport1 = + createViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, virtualUniqueId1, NO_PORT, ViewportType::VIRTUAL); + mFakePolicy->addDisplayViewport(virtualViewport1); // Add another virtual viewport - mFakePolicy->addDisplayViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /*isActive=*/true, virtualUniqueId2, NO_PORT, - ViewportType::VIRTUAL); + DisplayViewport virtualViewport2 = + createViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, virtualUniqueId2, NO_PORT, ViewportType::VIRTUAL); + mFakePolicy->addDisplayViewport(virtualViewport2); // Check matching by type for internal - std::optional<DisplayViewport> internalViewport = + std::optional<DisplayViewport> receivedInternalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); - ASSERT_TRUE(internalViewport); - ASSERT_EQ(internalUniqueId, internalViewport->uniqueId); + ASSERT_TRUE(receivedInternalViewport.has_value()); + ASSERT_EQ(internalViewport, *receivedInternalViewport); // Check matching by type for external - std::optional<DisplayViewport> externalViewport = + std::optional<DisplayViewport> receivedExternalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::EXTERNAL); - ASSERT_TRUE(externalViewport); - ASSERT_EQ(externalUniqueId, externalViewport->uniqueId); + ASSERT_TRUE(receivedExternalViewport.has_value()); + ASSERT_EQ(externalViewport, *receivedExternalViewport); // Check matching by uniqueId for virtual viewport #1 - std::optional<DisplayViewport> virtualViewport1 = + std::optional<DisplayViewport> receivedVirtualViewport1 = mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId1); - ASSERT_TRUE(virtualViewport1); - ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport1->type); - ASSERT_EQ(virtualUniqueId1, virtualViewport1->uniqueId); - ASSERT_EQ(virtualDisplayId1, virtualViewport1->displayId); + ASSERT_TRUE(receivedVirtualViewport1.has_value()); + ASSERT_EQ(virtualViewport1, *receivedVirtualViewport1); // Check matching by uniqueId for virtual viewport #2 - std::optional<DisplayViewport> virtualViewport2 = + std::optional<DisplayViewport> receivedVirtualViewport2 = mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId2); - ASSERT_TRUE(virtualViewport2); - ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport2->type); - ASSERT_EQ(virtualUniqueId2, virtualViewport2->uniqueId); - ASSERT_EQ(virtualDisplayId2, virtualViewport2->displayId); + ASSERT_TRUE(receivedVirtualViewport2.has_value()); + ASSERT_EQ(virtualViewport2, *receivedVirtualViewport2); } @@ -481,24 +481,26 @@ TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) { for (const ViewportType& type : types) { mFakePolicy->clearViewports(); // Add a viewport - mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, uniqueId1, NO_PORT, type); + DisplayViewport viewport1 = + createViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, uniqueId1, NO_PORT, type); + mFakePolicy->addDisplayViewport(viewport1); // Add another viewport - mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, uniqueId2, NO_PORT, type); + DisplayViewport viewport2 = + createViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, uniqueId2, NO_PORT, type); + mFakePolicy->addDisplayViewport(viewport2); // Check that correct display viewport was returned by comparing the display IDs. - std::optional<DisplayViewport> viewport1 = + std::optional<DisplayViewport> receivedViewport1 = mFakePolicy->getDisplayViewportByUniqueId(uniqueId1); - ASSERT_TRUE(viewport1); - ASSERT_EQ(displayId1, viewport1->displayId); - ASSERT_EQ(type, viewport1->type); + ASSERT_TRUE(receivedViewport1.has_value()); + ASSERT_EQ(viewport1, *receivedViewport1); - std::optional<DisplayViewport> viewport2 = + std::optional<DisplayViewport> receivedViewport2 = mFakePolicy->getDisplayViewportByUniqueId(uniqueId2); - ASSERT_TRUE(viewport2); - ASSERT_EQ(displayId2, viewport2->displayId); - ASSERT_EQ(type, viewport2->type); + ASSERT_TRUE(receivedViewport2.has_value()); + ASSERT_EQ(viewport2, *receivedViewport2); // When there are multiple viewports of the same kind, and uniqueId is not specified // in the call to getDisplayViewport, then that situation is not supported. @@ -524,32 +526,27 @@ TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) { // Add the default display first and ensure it gets returned. mFakePolicy->clearViewports(); - mFakePolicy->addDisplayViewport(ui::LogicalDisplayId::DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /*isActive=*/true, uniqueId1, NO_PORT, - ViewportType::INTERNAL); - mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /*isActive=*/true, uniqueId2, NO_PORT, - ViewportType::INTERNAL); - - std::optional<DisplayViewport> viewport = + DisplayViewport viewport1 = createViewport(ui::LogicalDisplayId::DEFAULT, DISPLAY_WIDTH, + DISPLAY_HEIGHT, ui::ROTATION_0, /*isActive=*/true, + uniqueId1, NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(viewport1); + DisplayViewport viewport2 = + createViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, uniqueId2, NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(viewport2); + std::optional<DisplayViewport> receivedViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); - ASSERT_TRUE(viewport); - ASSERT_EQ(ui::LogicalDisplayId::DEFAULT, viewport->displayId); - ASSERT_EQ(ViewportType::INTERNAL, viewport->type); + ASSERT_TRUE(receivedViewport.has_value()); + ASSERT_EQ(viewport1, *receivedViewport); // Add the default display second to make sure order doesn't matter. mFakePolicy->clearViewports(); - mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /*isActive=*/true, uniqueId2, NO_PORT, - ViewportType::INTERNAL); - mFakePolicy->addDisplayViewport(ui::LogicalDisplayId::DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /*isActive=*/true, uniqueId1, NO_PORT, - ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(viewport2); + mFakePolicy->addDisplayViewport(viewport1); - viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); - ASSERT_TRUE(viewport); - ASSERT_EQ(ui::LogicalDisplayId::DEFAULT, viewport->displayId); - ASSERT_EQ(ViewportType::INTERNAL, viewport->type); + receivedViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); + ASSERT_TRUE(receivedViewport.has_value()); + ASSERT_EQ(viewport1, *receivedViewport); } /** @@ -567,28 +564,27 @@ TEST_F(InputReaderPolicyTest, Viewports_GetByPort) { mFakePolicy->clearViewports(); // Add a viewport that's associated with some display port that's not of interest. - mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, uniqueId1, hdmi3, type); + DisplayViewport viewport1 = + createViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, uniqueId1, hdmi3, type); + mFakePolicy->addDisplayViewport(viewport1); // Add another viewport, connected to HDMI1 port - mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, uniqueId2, hdmi1, type); - + DisplayViewport viewport2 = + createViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, uniqueId2, hdmi1, type); + mFakePolicy->addDisplayViewport(viewport2); // Check that correct display viewport was returned by comparing the display ports. std::optional<DisplayViewport> hdmi1Viewport = mFakePolicy->getDisplayViewportByPort(hdmi1); - ASSERT_TRUE(hdmi1Viewport); - ASSERT_EQ(displayId2, hdmi1Viewport->displayId); - ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId); + ASSERT_TRUE(hdmi1Viewport.has_value()); + ASSERT_EQ(viewport2, *hdmi1Viewport); // Check that we can still get the same viewport using the uniqueId hdmi1Viewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId2); - ASSERT_TRUE(hdmi1Viewport); - ASSERT_EQ(displayId2, hdmi1Viewport->displayId); - ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId); - ASSERT_EQ(type, hdmi1Viewport->type); + ASSERT_TRUE(hdmi1Viewport.has_value()); + ASSERT_EQ(viewport2, *hdmi1Viewport); // Check that we cannot find a port with "HDMI2", because we never added one - std::optional<DisplayViewport> hdmi2Viewport = mFakePolicy->getDisplayViewportByPort(hdmi2); - ASSERT_FALSE(hdmi2Viewport); + ASSERT_FALSE(mFakePolicy->getDisplayViewportByPort(hdmi2)); } // --- InputReaderTest --- @@ -1045,11 +1041,14 @@ TEST_F(InputReaderTest, Device_CanDispatchToDisplay) { // Add default and second display. mFakePolicy->clearViewports(); - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL); - mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /*isActive=*/true, "local:1", hdmi1, - ViewportType::EXTERNAL); + DisplayViewport internalViewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(internalViewport); + DisplayViewport externalViewport = + createViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, "local:1", hdmi1, ViewportType::EXTERNAL); + mFakePolicy->addDisplayViewport(externalViewport); mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::DISPLAY_INFO); mReader->loopOnce(); @@ -1406,6 +1405,68 @@ TEST_F(InputReaderTest, SetPowerWakeUp) { ASSERT_EQ(mFakeEventHub->fakeReadKernelWakeup(3), false); } +TEST_F(InputReaderTest, MergeableInputDevices) { + constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1}; + + // By default, all of the default-created eventhub devices will have the same identifier + // (implicitly vid 0, pid 0, etc.), which is why we expect them to be merged. + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "1st", InputDeviceClass::KEYBOARD, nullptr)); + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "2nd", InputDeviceClass::JOYSTICK, nullptr)); + + // The two devices will be merged to one input device as they have same identifier, and none are + // pointer devices. + ASSERT_EQ(1U, mFakePolicy->getInputDevices().size()); +} + +TEST_F(InputReaderTest, MergeableDevicesWithTouch) { + constexpr int32_t eventHubIds[3] = {END_RESERVED_ID, END_RESERVED_ID + 1, END_RESERVED_ID + 2}; + + // By default, all of the default-created eventhub devices will have the same identifier + // (implicitly vid 0, pid 0, etc.), which is why we expect them to be merged. + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "1st", InputDeviceClass::TOUCH_MT, nullptr)); + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "2nd", InputDeviceClass::KEYBOARD, nullptr)); + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[2], "3rd", InputDeviceClass::GAMEPAD, nullptr)); + + // The three devices will be merged to one input device as they have same identifier, and only + // one is a pointer device. + ASSERT_EQ(1U, mFakePolicy->getInputDevices().size()); +} + +TEST_F(InputReaderTest, UnmergeableTouchDevices) { + SCOPED_FLAG_OVERRIDE(prevent_merging_input_pointer_devices, true); + + constexpr int32_t eventHubIds[3] = {END_RESERVED_ID, END_RESERVED_ID + 1, END_RESERVED_ID + 2}; + + // By default, all of the default-created eventhub devices will have the same identifier + // (implicitly vid 0, pid 0, etc.), which is why they can potentially be merged. + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "1st", InputDeviceClass::TOUCH, nullptr)); + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "2nd", InputDeviceClass::TOUCH_MT, nullptr)); + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[2], "2nd", InputDeviceClass::CURSOR, nullptr)); + + // The three devices will not be merged, as they have same identifier, but are all pointer + // devices. + ASSERT_EQ(3U, mFakePolicy->getInputDevices().size()); +} + +TEST_F(InputReaderTest, MergeableMixedDevices) { + SCOPED_FLAG_OVERRIDE(prevent_merging_input_pointer_devices, true); + + constexpr int32_t eventHubIds[4] = {END_RESERVED_ID, END_RESERVED_ID + 1, END_RESERVED_ID + 2, + END_RESERVED_ID + 3}; + + // By default, all of the default-created eventhub devices will have the same identifier + // (implicitly vid 0, pid 0, etc.), which is why they can potentially be merged. + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "1st", InputDeviceClass::TOUCH, nullptr)); + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "2nd", InputDeviceClass::TOUCH_MT, nullptr)); + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[2], "3rd", InputDeviceClass::DPAD, nullptr)); + ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[3], "4th", InputDeviceClass::JOYSTICK, nullptr)); + + // Non-touch devices can be merged with one of the touch devices, as they have same identifier, + // but the two touch devices will not combine with each other. It is not specified which touch + // device the non-touch devices merge with. + ASSERT_EQ(2U, mFakePolicy->getInputDevices().size()); +} + // --- InputReaderIntegrationTest --- // These tests create and interact with the InputReader only through its interface. @@ -1652,7 +1713,7 @@ protected: mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT)); ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged()); const auto info = waitForDevice(mDevice->getName()); - ASSERT_TRUE(info); + ASSERT_TRUE(info.has_value()); mDeviceInfo = *info; } @@ -1660,8 +1721,10 @@ protected: ui::Rotation orientation, const std::string& uniqueId, std::optional<uint8_t> physicalPort, ViewportType viewportType) { - mFakePolicy->addDisplayViewport(displayId, width, height, orientation, /*isActive=*/true, - uniqueId, physicalPort, viewportType); + DisplayViewport viewport = + createViewport(displayId, width, height, orientation, /*isActive=*/true, uniqueId, + physicalPort, viewportType); + mFakePolicy->addDisplayViewport(viewport); mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::DISPLAY_INFO); } @@ -1720,7 +1783,7 @@ protected: ViewportType::INTERNAL); ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged()); const auto info = waitForDevice(mDevice->getName()); - ASSERT_TRUE(info); + ASSERT_TRUE(info.has_value()); mDeviceInfo = *info; } }; @@ -2052,7 +2115,7 @@ TEST_P(TouchIntegrationTest, ExternalStylusConnectedDuringTouchGesture) { auto externalStylus = createUinputDevice<UinputExternalStylus>(); ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged()); const auto stylusInfo = waitForDevice(externalStylus->getName()); - ASSERT_TRUE(stylusInfo); + ASSERT_TRUE(stylusInfo.has_value()); // Move mDevice->sendMove(centerPoint + Point(2, 2)); @@ -2121,7 +2184,7 @@ private: mStylus = mStylusDeviceLifecycleTracker.get(); ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged()); const auto info = waitForDevice(mStylus->getName()); - ASSERT_TRUE(info); + ASSERT_TRUE(info.has_value()); mStylusInfo = *info; } @@ -2394,7 +2457,7 @@ TEST_F(ExternalStylusIntegrationTest, ExternalStylusConnectionChangesTouchscreen // Connecting an external stylus changes the source of the touchscreen. const auto deviceInfo = waitForDevice(mDevice->getName()); - ASSERT_TRUE(deviceInfo); + ASSERT_TRUE(deviceInfo.has_value()); ASSERT_TRUE(isFromSource(deviceInfo->getSources(), STYLUS_FUSION_SOURCE)); } @@ -2407,7 +2470,7 @@ TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureReported) { createUinputDevice<UinputExternalStylusWithPressure>(); ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged()); const auto stylusInfo = waitForDevice(stylus->getName()); - ASSERT_TRUE(stylusInfo); + ASSERT_TRUE(stylusInfo.has_value()); ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources()); @@ -2452,7 +2515,7 @@ TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) { createUinputDevice<UinputExternalStylusWithPressure>(); ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged()); const auto stylusInfo = waitForDevice(stylus->getName()); - ASSERT_TRUE(stylusInfo); + ASSERT_TRUE(stylusInfo.has_value()); ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources()); @@ -2879,9 +2942,10 @@ TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) { ASSERT_FALSE(mDevice->isEnabled()); // Prepare displays. - mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /*isActive=*/true, UNIQUE_ID, hdmi, - ViewportType::INTERNAL); + DisplayViewport viewport = + createViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, UNIQUE_ID, hdmi, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(viewport); unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), InputReaderConfiguration::Change::DISPLAY_INFO); ASSERT_TRUE(mDevice->isEnabled()); @@ -2916,9 +2980,12 @@ TEST_F(InputDeviceTest, Configure_AssignsDisplayUniqueId) { ASSERT_FALSE(mDevice->isEnabled()); // Device should be enabled when a display is found. - mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID, - NO_PORT, ViewportType::INTERNAL); + + DisplayViewport secondViewport = + createViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /* isActive= */ true, DISPLAY_UNIQUE_ID, NO_PORT, + ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(secondViewport); unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), InputReaderConfiguration::Change::DISPLAY_INFO); ASSERT_TRUE(mDevice->isEnabled()); @@ -2944,9 +3011,12 @@ TEST_F(InputDeviceTest, Configure_UniqueId_CorrectlyMatches) { /*changes=*/{}); mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID); - mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - ui::ROTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID, - NO_PORT, ViewportType::INTERNAL); + + DisplayViewport secondViewport = + createViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /* isActive= */ true, DISPLAY_UNIQUE_ID, NO_PORT, + ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(secondViewport); const auto initialGeneration = mDevice->getGeneration(); unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), InputReaderConfiguration::Change::DISPLAY_INFO); @@ -4526,6 +4596,10 @@ TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { NotifyMotionArgs motionArgs; + // Hold down the mouse button for the duration of the test, since the mouse tools require + // the button to be pressed to make sure they are not hovering. + processKey(mapper, BTN_MOUSE, 1); + // default tool type is finger processDown(mapper, 100, 200); processSync(mapper); @@ -4533,6 +4607,9 @@ TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS))); + // eraser processKey(mapper, BTN_TOOL_RUBBER, 1); processSync(mapper); @@ -7175,6 +7252,10 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { NotifyMotionArgs motionArgs; + // Hold down the mouse button for the duration of the test, since the mouse tools require + // the button to be pressed to make sure they are not hovering. + processKey(mapper, BTN_MOUSE, 1); + // default tool type is finger processId(mapper, 1); processPosition(mapper, 100, 200); @@ -7183,6 +7264,9 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS))); + // eraser processKey(mapper, BTN_TOOL_RUBBER, 1); processSync(mapper); @@ -7349,35 +7433,39 @@ TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIs toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); // down when BTN_TOUCH is pressed, pressure defaults to 1 + processPosition(mapper, 151, 251); processKey(mapper, BTN_TOUCH, 1); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action); + // HOVER_EXIT should have the same coordinates as the previous HOVER_MOVE ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); - + // down at the new position ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0)); + toDisplayX(151), toDisplayY(251), 1, 0, 0, 0, 0, 0, 0, 0)); // up when BTN_TOUCH is released, hover restored + processPosition(mapper, 152, 252); processKey(mapper, BTN_TOUCH, 0); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action); + // UP should have the same coordinates as the previous event ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0)); - + toDisplayX(151), toDisplayY(251), 1, 0, 0, 0, 0, 0, 0, 0)); + // HOVER_ENTER at the new position ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); + toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0)); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); + toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0)); // exit hover when pointer goes away processId(mapper, -1); @@ -7385,7 +7473,7 @@ TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIs ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); + toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0)); } TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) { @@ -7420,35 +7508,39 @@ TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfIts toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); // down when pressure becomes non-zero + processPosition(mapper, 151, 251); processPressure(mapper, RAW_PRESSURE_MAX); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action); + // HOVER_EXIT should have the same coordinates as the previous HOVER_MOVE ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); - + // down at the new position ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0)); + toDisplayX(151), toDisplayY(251), 1, 0, 0, 0, 0, 0, 0, 0)); // up when pressure becomes 0, hover restored + processPosition(mapper, 152, 252); processPressure(mapper, 0); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action); + // UP should have the same coordinates as the previous event ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0)); - + toDisplayX(151), toDisplayY(251), 1, 0, 0, 0, 0, 0, 0, 0)); + // HOVER_ENTER at the new position ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); + toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0)); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); + toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0)); // exit hover when pointer goes away processId(mapper, -1); @@ -7456,7 +7548,7 @@ TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfIts ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], - toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); + toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0)); } /** @@ -7520,6 +7612,7 @@ TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayUniqueId) { } TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) { + SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, true); prepareSecondaryDisplay(ViewportType::EXTERNAL); prepareDisplay(ui::ROTATION_0); @@ -7532,9 +7625,9 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) { processPosition(mapper, 100, 100); processSync(mapper); - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); - ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action); - ASSERT_EQ(ui::LogicalDisplayId::INVALID, motionArgs.displayId); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithDisplayId(DISPLAY_ID), + WithSource(AINPUT_SOURCE_MOUSE), WithToolType(ToolType::FINGER)))); } /** @@ -7570,8 +7663,10 @@ TEST_F(MultiTouchInputMapperTest, Process_SendsReadTime) { TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) { addConfigurationProperty("touch.deviceType", "touchScreen"); // Don't set touch.enableForInactiveViewport to verify the default behavior. - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL); + DisplayViewport viewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(viewport); configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO); prepareAxes(POSITION); MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>(); @@ -7590,8 +7685,10 @@ TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) { TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreProcessed) { addConfigurationProperty("touch.deviceType", "touchScreen"); addConfigurationProperty("touch.enableForInactiveViewport", "1"); - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL); + DisplayViewport viewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(viewport); configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO); prepareAxes(POSITION); MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>(); @@ -7612,8 +7709,10 @@ TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreProcessed) { TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) { addConfigurationProperty("touch.deviceType", "touchScreen"); addConfigurationProperty("touch.enableForInactiveViewport", "0"); - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL); + DisplayViewport viewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(viewport); std::optional<DisplayViewport> optionalDisplayViewport = mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID); ASSERT_TRUE(optionalDisplayViewport.has_value()); @@ -7668,12 +7767,10 @@ TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) { TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_TouchesNotAborted) { addConfigurationProperty("touch.deviceType", "touchScreen"); addConfigurationProperty("touch.enableForInactiveViewport", "1"); - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL); - std::optional<DisplayViewport> optionalDisplayViewport = - mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID); - ASSERT_TRUE(optionalDisplayViewport.has_value()); - DisplayViewport displayViewport = *optionalDisplayViewport; + DisplayViewport displayViewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(displayViewport); configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO); prepareAxes(POSITION); @@ -8406,41 +8503,6 @@ TEST_F(MultiTouchInputMapperTest, StylusSourceIsAddedDynamicallyFromToolType) { WithToolType(ToolType::STYLUS)))); } -// --- MultiTouchInputMapperTest_ExternalDevice --- - -class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest { -protected: - void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); } -}; - -/** - * Expect fallback to internal viewport if device is external and external viewport is not present. - */ -TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) { - prepareAxes(POSITION); - addConfigurationProperty("touch.deviceType", "touchScreen"); - prepareDisplay(ui::ROTATION_0); - MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>(); - - ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources()); - - NotifyMotionArgs motionArgs; - - // Expect the event to be sent to the internal viewport, - // because an external viewport is not present. - processPosition(mapper, 100, 100); - processSync(mapper); - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); - ASSERT_EQ(ui::LogicalDisplayId::DEFAULT, motionArgs.displayId); - - // Expect the event to be sent to the external viewport if it is present. - prepareSecondaryDisplay(ViewportType::EXTERNAL); - processPosition(mapper, 100, 100); - processSync(mapper); - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs)); - ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId); -} - // TODO(b/281840344): Remove the test when the old touchpad stack is removed. It is currently // unclear what the behavior of the touchpad logic in TouchInputMapper should do after the // PointerChoreographer refactor. @@ -8604,6 +8666,8 @@ protected: * fingers start to move downwards, the gesture should be swipe. */ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) { + SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false); + // The min freeform gesture width is 25units/mm x 30mm = 750 // which is greater than fraction of the diagnal length of the touchpad (349). // Thus, MaxSwipWidth is 750. @@ -8664,6 +8728,8 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) { * the gesture should be swipe. */ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) { + SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false); + // The min freeform gesture width is 5units/mm x 30mm = 150 // which is greater than fraction of the diagnal length of the touchpad (349). // Thus, MaxSwipWidth is the fraction of the diagnal length, 349. @@ -8723,6 +8789,8 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) * freeform gestures after two fingers start to move downwards. */ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) { + SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false); + preparePointerMode(/*xResolution=*/25, /*yResolution=*/25); MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>(); @@ -8818,6 +8886,8 @@ TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) { } TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) { + SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false); + preparePointerMode(/*xResolution=*/25, /*yResolution=*/25); MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>(); NotifyMotionArgs motionArgs; @@ -8864,6 +8934,8 @@ TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) { } TEST_F(MultiTouchPointerModeTest, WhenViewportActiveStatusChanged_PointerGestureIsReset) { + SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false); + preparePointerMode(/*xResolution=*/25, /*yResolution=*/25); mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0); MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>(); diff --git a/services/inputflinger/tests/InstrumentedInputReader.cpp b/services/inputflinger/tests/InstrumentedInputReader.cpp index 110ca5fab0..53fc8a1f58 100644 --- a/services/inputflinger/tests/InstrumentedInputReader.cpp +++ b/services/inputflinger/tests/InstrumentedInputReader.cpp @@ -38,13 +38,14 @@ std::shared_ptr<InputDevice> InstrumentedInputReader::newDevice(int32_t deviceId } std::shared_ptr<InputDevice> InstrumentedInputReader::createDeviceLocked( - nsecs_t when, int32_t eventHubId, const InputDeviceIdentifier& identifier) REQUIRES(mLock) { + nsecs_t when, int32_t eventHubId, const InputDeviceIdentifier& identifier, + ftl::Flags<InputDeviceClass> classes) REQUIRES(mLock) { if (!mNextDevices.empty()) { std::shared_ptr<InputDevice> device(std::move(mNextDevices.front())); mNextDevices.pop(); return device; } - return InputReader::createDeviceLocked(when, eventHubId, identifier); + return InputReader::createDeviceLocked(when, eventHubId, identifier, classes); } } // namespace android diff --git a/services/inputflinger/tests/InstrumentedInputReader.h b/services/inputflinger/tests/InstrumentedInputReader.h index e9c7bb44e8..9abf30c569 100644 --- a/services/inputflinger/tests/InstrumentedInputReader.h +++ b/services/inputflinger/tests/InstrumentedInputReader.h @@ -43,8 +43,9 @@ public: using InputReader::loopOnce; protected: - virtual std::shared_ptr<InputDevice> createDeviceLocked( - nsecs_t when, int32_t eventHubId, const InputDeviceIdentifier& identifier); + virtual std::shared_ptr<InputDevice> createDeviceLocked(nsecs_t when, int32_t eventHubId, + const InputDeviceIdentifier& identifier, + ftl::Flags<InputDeviceClass> classes); class FakeInputReaderContext : public ContextImpl { public: diff --git a/services/inputflinger/tests/InterfaceMocks.h b/services/inputflinger/tests/InterfaceMocks.h index ac616d0296..d4e4bb00f7 100644 --- a/services/inputflinger/tests/InterfaceMocks.h +++ b/services/inputflinger/tests/InterfaceMocks.h @@ -50,6 +50,8 @@ namespace android { class MockInputReaderContext : public InputReaderContext { public: + std::string dump() override { return "(dump from MockInputReaderContext)"; } + MOCK_METHOD(void, updateGlobalMetaState, (), (override)); MOCK_METHOD(int32_t, getGlobalMetaState, (), (override)); @@ -68,7 +70,7 @@ public: MOCK_METHOD(InputReaderPolicyInterface*, getPolicy, (), (override)); MOCK_METHOD(EventHubInterface*, getEventHub, (), (override)); - int32_t getNextId() override { return 1; }; + int32_t getNextId() const override { return 1; }; MOCK_METHOD(void, updateLedMetaState, (int32_t metaState), (override)); MOCK_METHOD(int32_t, getLedMetaState, (), (override)); @@ -191,19 +193,22 @@ public: (ui::LogicalDisplayId displayId, const vec2& position), (override)); MOCK_METHOD(bool, isInputMethodConnectionActive, (), (override)); MOCK_METHOD(void, notifyMouseCursorFadedOnTyping, (), (override)); + MOCK_METHOD(std::optional<vec2>, filterPointerMotionForAccessibility, + (const vec2& current, const vec2& delta, const ui::LogicalDisplayId& displayId), + (override)); }; class MockInputDevice : public InputDevice { public: MockInputDevice(InputReaderContext* context, int32_t id, int32_t generation, - const InputDeviceIdentifier& identifier) - : InputDevice(context, id, generation, identifier) {} + const InputDeviceIdentifier& identifier, bool isExternal) + : InputDevice(context, id, generation, identifier), mIsExternal(isExternal) {} MOCK_METHOD(uint32_t, getSources, (), (const, override)); MOCK_METHOD(std::optional<DisplayViewport>, getAssociatedViewport, (), (const)); MOCK_METHOD(KeyboardType, getKeyboardType, (), (const, override)); MOCK_METHOD(bool, isEnabled, (), ()); - MOCK_METHOD(bool, isExternal, (), (override)); + bool isExternal() override { return mIsExternal; } MOCK_METHOD(void, dump, (std::string& dump, const std::string& eventHubDevStr), ()); MOCK_METHOD(void, addEmptyEventHubDevice, (int32_t eventHubId), ()); @@ -266,5 +271,6 @@ public: private: int32_t mGeneration = 0; + const bool mIsExternal; }; } // namespace android diff --git a/services/inputflinger/tests/KeyboardInputMapper_test.cpp b/services/inputflinger/tests/KeyboardInputMapper_test.cpp index 1dd32c447b..d4b15bca48 100644 --- a/services/inputflinger/tests/KeyboardInputMapper_test.cpp +++ b/services/inputflinger/tests/KeyboardInputMapper_test.cpp @@ -176,16 +176,22 @@ protected: return std::get<NotifyKeyArgs>(args.front()); } - void testDPadKeyRotation(int32_t originalEvdevCode, int32_t originalKeyCode, - int32_t rotatedKeyCode, ui::LogicalDisplayId displayId = DISPLAY_ID) { - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, originalEvdevCode, 1); + std::list<NotifyArgs> processKeyAndSync(nsecs_t when, int32_t code, int32_t value) { + std::list<NotifyArgs> argsList = process(when, EV_KEY, code, value); + argsList += process(when, EV_SYN, SYN_REPORT, 0); + return argsList; + } + + void testDPadKeyRotation(int32_t originalEvdevCode, int32_t rotatedKeyCode, + ui::LogicalDisplayId displayId = DISPLAY_ID) { + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, originalEvdevCode, 1); NotifyKeyArgs args = expectSingleKeyArg(argsList); ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); ASSERT_EQ(originalEvdevCode, args.scanCode); ASSERT_EQ(rotatedKeyCode, args.keyCode); ASSERT_EQ(displayId, args.displayId); - argsList = process(ARBITRARY_TIME, EV_KEY, originalEvdevCode, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, originalEvdevCode, 0); args = expectSingleKeyArg(argsList); ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); ASSERT_EQ(originalEvdevCode, args.scanCode); @@ -205,23 +211,16 @@ TEST_F(KeyboardInputMapperUnitTest, KeyPressTimestampRecorded) { .With(Args<0>(when)) .Times(keyCodes.size()); for (int32_t keyCode : keyCodes) { - process(when, EV_KEY, keyCode, 1); - process(when, EV_SYN, SYN_REPORT, 0); - process(when, EV_KEY, keyCode, 0); - process(when, EV_SYN, SYN_REPORT, 0); + processKeyAndSync(when, keyCode, 1); + processKeyAndSync(when, keyCode, 0); } } TEST_F(KeyboardInputMapperUnitTest, RepeatEventsDiscarded) { std::list<NotifyArgs> args; - args += process(ARBITRARY_TIME, EV_KEY, KEY_0, 1); - args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); - - args += process(ARBITRARY_TIME, EV_KEY, KEY_0, 2); - args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); - - args += process(ARBITRARY_TIME, EV_KEY, KEY_0, 0); - args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); + args += processKeyAndSync(ARBITRARY_TIME, KEY_0, 1); + args += processKeyAndSync(ARBITRARY_TIME, KEY_0, 2); + args += processKeyAndSync(ARBITRARY_TIME, KEY_0, 0); EXPECT_THAT(args, ElementsAre(VariantWith<NotifyKeyArgs>(AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), @@ -241,7 +240,7 @@ TEST_F(KeyboardInputMapperUnitTest, Process_SimpleKeyPress) { ASSERT_EQ(AMETA_NONE, mMapper->getMetaState()); // Key down by evdev code. - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_HOME, 1); NotifyKeyArgs args = expectSingleKeyArg(argsList); ASSERT_EQ(DEVICE_ID, args.deviceId); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); @@ -255,7 +254,7 @@ TEST_F(KeyboardInputMapperUnitTest, Process_SimpleKeyPress) { ASSERT_EQ(ARBITRARY_TIME, args.downTime); // Key up by evdev code. - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_HOME, 0); args = expectSingleKeyArg(argsList); ASSERT_EQ(DEVICE_ID, args.deviceId); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); @@ -271,6 +270,7 @@ TEST_F(KeyboardInputMapperUnitTest, Process_SimpleKeyPress) { // Key down by usage code. argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_A); argsList += process(ARBITRARY_TIME, EV_KEY, 0, 1); + argsList += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); args = expectSingleKeyArg(argsList); ASSERT_EQ(DEVICE_ID, args.deviceId); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); @@ -284,8 +284,9 @@ TEST_F(KeyboardInputMapperUnitTest, Process_SimpleKeyPress) { ASSERT_EQ(ARBITRARY_TIME, args.downTime); // Key up by usage code. - argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_A); + argsList = process(ARBITRARY_TIME + 1, EV_MSC, MSC_SCAN, USAGE_A); argsList += process(ARBITRARY_TIME + 1, EV_KEY, 0, 0); + argsList += process(ARBITRARY_TIME + 1, EV_SYN, SYN_REPORT, 0); args = expectSingleKeyArg(argsList); ASSERT_EQ(DEVICE_ID, args.deviceId); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); @@ -307,6 +308,7 @@ TEST_F(KeyboardInputMapperUnitTest, Process_UnknownKey) { // Key down with unknown scan code or usage code. std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN); argsList += process(ARBITRARY_TIME, EV_KEY, KEY_UNKNOWN, 1); + argsList += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); NotifyKeyArgs args = expectSingleKeyArg(argsList); ASSERT_EQ(DEVICE_ID, args.deviceId); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); @@ -320,8 +322,9 @@ TEST_F(KeyboardInputMapperUnitTest, Process_UnknownKey) { ASSERT_EQ(ARBITRARY_TIME, args.downTime); // Key up with unknown scan code or usage code. - argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN); + argsList = process(ARBITRARY_TIME + 1, EV_MSC, MSC_SCAN, USAGE_UNKNOWN); argsList += process(ARBITRARY_TIME + 1, EV_KEY, KEY_UNKNOWN, 0); + argsList += process(ARBITRARY_TIME + 1, EV_SYN, SYN_REPORT, 0); args = expectSingleKeyArg(argsList); ASSERT_EQ(DEVICE_ID, args.deviceId); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); @@ -343,10 +346,12 @@ TEST_F(KeyboardInputMapperUnitTest, Process_SendsReadTime) { // Key down std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, /*readTime=*/12, EV_KEY, KEY_HOME, 1); + argsList += process(ARBITRARY_TIME, /*readTime=*/12, EV_SYN, SYN_REPORT, 0); ASSERT_EQ(12, expectSingleKeyArg(argsList).readTime); // Key up - argsList = process(ARBITRARY_TIME, /*readTime=*/15, EV_KEY, KEY_HOME, 1); + argsList = process(ARBITRARY_TIME, /*readTime=*/15, EV_KEY, KEY_HOME, 0); + argsList += process(ARBITRARY_TIME, /*readTime=*/15, EV_SYN, SYN_REPORT, 0); ASSERT_EQ(15, expectSingleKeyArg(argsList).readTime); } @@ -360,22 +365,22 @@ TEST_F(KeyboardInputMapperUnitTest, Process_ShouldUpdateMetaState) { ASSERT_EQ(AMETA_NONE, mMapper->getMetaState()); // Metakey down. - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_LEFTSHIFT, 1); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_LEFTSHIFT, 1); ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, expectSingleKeyArg(argsList).metaState); ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mMapper->getMetaState()); // Key down. - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_A, 1); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_A, 1); ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, expectSingleKeyArg(argsList).metaState); ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mMapper->getMetaState()); // Key up. - argsList = process(ARBITRARY_TIME + 2, EV_KEY, KEY_A, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 2, KEY_A, 0); ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, expectSingleKeyArg(argsList).metaState); ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mMapper->getMetaState()); // Metakey up. - argsList = process(ARBITRARY_TIME + 3, EV_KEY, KEY_LEFTSHIFT, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 3, KEY_LEFTSHIFT, 0); ASSERT_EQ(AMETA_NONE, expectSingleKeyArg(argsList).metaState); ASSERT_EQ(AMETA_NONE, mMapper->getMetaState()); } @@ -387,11 +392,10 @@ TEST_F(KeyboardInputMapperUnitTest, Process_WhenNotOrientationAware_ShouldNotRot addKeyByEvdevCode(KEY_LEFT, AKEYCODE_DPAD_LEFT); setDisplayOrientation(ui::Rotation::Rotation90); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP)); - ASSERT_NO_FATAL_FAILURE( - testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT)); } TEST_F(KeyboardInputMapperUnitTest, Process_WhenOrientationAware_ShouldRotateDPad) { @@ -405,43 +409,40 @@ TEST_F(KeyboardInputMapperUnitTest, Process_WhenOrientationAware_ShouldRotateDPa AINPUT_SOURCE_KEYBOARD); setDisplayOrientation(ui::ROTATION_0); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP)); - ASSERT_NO_FATAL_FAILURE( - testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT)); setDisplayOrientation(ui::ROTATION_90); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_LEFT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_UP)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_RIGHT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_DOWN)); setDisplayOrientation(ui::ROTATION_180); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN)); - ASSERT_NO_FATAL_FAILURE( - testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_LEFT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_UP)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_RIGHT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_DOWN)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_LEFT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_UP)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_RIGHT)); setDisplayOrientation(ui::ROTATION_270); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT)); - ASSERT_NO_FATAL_FAILURE( - testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_DOWN)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_LEFT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_UP)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_RIGHT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_DOWN)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_LEFT)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_UP)); // Special case: if orientation changes while key is down, we still emit the same keycode // in the key up as we did in the key down. setDisplayOrientation(ui::ROTATION_270); - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 1); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_UP, 1); NotifyKeyArgs args = expectSingleKeyArg(argsList); ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); ASSERT_EQ(KEY_UP, args.scanCode); ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode); setDisplayOrientation(ui::ROTATION_180); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_UP, 0); args = expectSingleKeyArg(argsList); ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); ASSERT_EQ(KEY_UP, args.scanCode); @@ -454,9 +455,9 @@ TEST_F(KeyboardInputMapperUnitTest, DisplayIdConfigurationChange_NotOrientationA addKeyByEvdevCode(KEY_UP, AKEYCODE_DPAD_UP); // Display id should be LogicalDisplayId::INVALID without any display configuration. - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 1); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_UP, 1); ASSERT_GT(argsList.size(), 0u); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_UP, 0); ASSERT_GT(argsList.size(), 0u); ASSERT_EQ(ui::LogicalDisplayId::INVALID, std::get<NotifyKeyArgs>(argsList.front()).displayId); } @@ -474,9 +475,9 @@ TEST_F(KeyboardInputMapperUnitTest, DisplayIdConfigurationChange_OrientationAwar // ^--- already checked by the previous test setDisplayOrientation(ui::ROTATION_0); - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 1); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_UP, 1); ASSERT_GT(argsList.size(), 0u); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_UP, 0); ASSERT_GT(argsList.size(), 0u); ASSERT_EQ(DISPLAY_ID, std::get<NotifyKeyArgs>(argsList.front()).displayId); @@ -487,9 +488,9 @@ TEST_F(KeyboardInputMapperUnitTest, DisplayIdConfigurationChange_OrientationAwar argsList = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, InputReaderConfiguration::Change::DISPLAY_INFO); ASSERT_EQ(0u, argsList.size()); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_UP, 1); ASSERT_GT(argsList.size(), 0u); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_UP, 0); ASSERT_GT(argsList.size(), 0u); ASSERT_EQ(newDisplayId, std::get<NotifyKeyArgs>(argsList.front()).displayId); } @@ -565,48 +566,48 @@ TEST_F(KeyboardInputMapperUnitTest, Process_LockedKeysShouldToggleMetaStateAndLe ASSERT_FALSE(scrollLockLed); // Toggle caps lock on. - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 1); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 0); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_CAPSLOCK, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_CAPSLOCK, 0); ASSERT_TRUE(capsLockLed); ASSERT_FALSE(numLockLed); ASSERT_FALSE(scrollLockLed); ASSERT_EQ(AMETA_CAPS_LOCK_ON, mMapper->getMetaState()); // Toggle num lock on. - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_NUMLOCK, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_NUMLOCK, 0); ASSERT_TRUE(capsLockLed); ASSERT_TRUE(numLockLed); ASSERT_FALSE(scrollLockLed); ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mMapper->getMetaState()); // Toggle caps lock off. - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 1); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_CAPSLOCK, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_CAPSLOCK, 0); ASSERT_FALSE(capsLockLed); ASSERT_TRUE(numLockLed); ASSERT_FALSE(scrollLockLed); ASSERT_EQ(AMETA_NUM_LOCK_ON, mMapper->getMetaState()); // Toggle scroll lock on. - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_SCROLLLOCK, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_SCROLLLOCK, 0); ASSERT_FALSE(capsLockLed); ASSERT_TRUE(numLockLed); ASSERT_TRUE(scrollLockLed); ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mMapper->getMetaState()); // Toggle num lock off. - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_NUMLOCK, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_NUMLOCK, 0); ASSERT_FALSE(capsLockLed); ASSERT_FALSE(numLockLed); ASSERT_TRUE(scrollLockLed); ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mMapper->getMetaState()); // Toggle scroll lock off. - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 0); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_SCROLLLOCK, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_SCROLLLOCK, 0); ASSERT_FALSE(capsLockLed); ASSERT_FALSE(numLockLed); ASSERT_FALSE(scrollLockLed); @@ -618,8 +619,8 @@ TEST_F(KeyboardInputMapperUnitTest, DisablingDeviceResetsPressedKeys) { addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME, POLICY_FLAG_WAKE); addKeyByUsageCode(USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE); - // Key down by scan code. - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1); + // Key down by evdev code. + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_HOME, 1); NotifyKeyArgs args = expectSingleKeyArg(argsList); ASSERT_EQ(DEVICE_ID, args.deviceId); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); @@ -685,37 +686,168 @@ TEST_F(KeyboardInputMapperUnitTest, Process_GestureEventToSetFlagKeepTouchMode) addKeyByEvdevCode(KEY_LEFT, AKEYCODE_DPAD_LEFT, POLICY_FLAG_GESTURE); // Key down - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_LEFT, 1); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_LEFT, 1); ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_KEEP_TOUCH_MODE, expectSingleKeyArg(argsList).flags); } -TEST_F_WITH_FLAGS(KeyboardInputMapperUnitTest, WakeBehavior_AlphabeticKeyboard, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags, - enable_alphabetic_keyboard_wake))) { - // For internal alphabetic devices, keys will trigger wake on key down. +// --- KeyboardInputMapperUnitTest_WakeFlagOverride --- + +class KeyboardInputMapperUnitTest_WakeFlagOverride : public KeyboardInputMapperUnitTest { +protected: + virtual void SetUp() override { + SetUp(/*wakeFlag=*/com::android::input::flags::enable_alphabetic_keyboard_wake()); + } + + void SetUp(bool wakeFlag) { + mWakeFlagInitialValue = com::android::input::flags::enable_alphabetic_keyboard_wake(); + com::android::input::flags::enable_alphabetic_keyboard_wake(wakeFlag); + KeyboardInputMapperUnitTest::SetUp(); + } + + void TearDown() override { + com::android::input::flags::enable_alphabetic_keyboard_wake(mWakeFlagInitialValue); + KeyboardInputMapperUnitTest::TearDown(); + } + + bool mWakeFlagInitialValue; +}; + +// --- KeyboardInputMapperUnitTest_NonAlphabeticKeyboard_WakeFlagEnabled --- + +class KeyboardInputMapperUnitTest_NonAlphabeticKeyboard_WakeFlagEnabled + : public KeyboardInputMapperUnitTest_WakeFlagOverride { +protected: + void SetUp() override { + KeyboardInputMapperUnitTest_WakeFlagOverride::SetUp(/*wakeFlag=*/true); + } +}; + +TEST_F(KeyboardInputMapperUnitTest_NonAlphabeticKeyboard_WakeFlagEnabled, + NonAlphabeticDevice_WakeBehavior) { + // For internal non-alphabetic devices keys will not trigger wake. addKeyByEvdevCode(KEY_A, AKEYCODE_A); addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME); addKeyByEvdevCode(KEY_PLAYPAUSE, AKEYCODE_MEDIA_PLAY_PAUSE); - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_A, 1); - ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_A, 1); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_A, 0); - ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_A, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1); - ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_HOME, 1); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0); - ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_HOME, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAYPAUSE, 1); - ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_PLAYPAUSE, 1); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAYPAUSE, 0); - ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_PLAYPAUSE, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); +} + +// --- KeyboardInputMapperUnitTest_AlphabeticKeyboard_WakeFlagEnabled --- + +class KeyboardInputMapperUnitTest_AlphabeticKeyboard_WakeFlagEnabled + : public KeyboardInputMapperUnitTest_WakeFlagOverride { +protected: + void SetUp() override { + KeyboardInputMapperUnitTest_WakeFlagOverride::SetUp(/*wakeFlag=*/true); + + ON_CALL((*mDevice), getKeyboardType).WillByDefault(Return(KeyboardType::ALPHABETIC)); + } +}; + +TEST_F(KeyboardInputMapperUnitTest_AlphabeticKeyboard_WakeFlagEnabled, WakeBehavior) { + // For internal alphabetic devices, keys will trigger wake on key down when + // flag is enabled. + addKeyByEvdevCode(KEY_A, AKEYCODE_A); + addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME); + addKeyByEvdevCode(KEY_PLAYPAUSE, AKEYCODE_MEDIA_PLAY_PAUSE); + + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_A, 1); + EXPECT_THAT(argsList, + ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(POLICY_FLAG_WAKE)))); + + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_A, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); + + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_HOME, 1); + EXPECT_THAT(argsList, + ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(POLICY_FLAG_WAKE)))); + + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_HOME, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); + + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_PLAYPAUSE, 1); + EXPECT_THAT(argsList, + ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(POLICY_FLAG_WAKE)))); + + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_PLAYPAUSE, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); +} + +TEST_F(KeyboardInputMapperUnitTest_AlphabeticKeyboard_WakeFlagEnabled, WakeBehavior_UnknownKey) { + // For internal alphabetic devices, unknown keys will trigger wake on key down when + // flag is enabled. + + const int32_t USAGE_UNKNOWN = 0x07ffff; + EXPECT_CALL(mMockEventHub, mapKey(EVENTHUB_ID, KEY_UNKNOWN, USAGE_UNKNOWN, _, _, _, _)) + .WillRepeatedly(Return(NAME_NOT_FOUND)); + + // Key down with unknown scan code or usage code. + std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN); + argsList += process(ARBITRARY_TIME, EV_KEY, KEY_UNKNOWN, 1); + EXPECT_THAT(argsList, + ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(POLICY_FLAG_WAKE)))); + + // Key up with unknown scan code or usage code. + argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN); + argsList += process(ARBITRARY_TIME + 1, EV_KEY, KEY_UNKNOWN, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); +} + +// --- KeyboardInputMapperUnitTest_AlphabeticDevice_AlphabeticKeyboardWakeDisabled --- + +class KeyboardInputMapperUnitTest_AlphabeticKeyboard_WakeFlagDisabled + : public KeyboardInputMapperUnitTest_WakeFlagOverride { +protected: + void SetUp() override { + KeyboardInputMapperUnitTest_WakeFlagOverride::SetUp(/*wakeFlag=*/false); + + ON_CALL((*mDevice), getKeyboardType).WillByDefault(Return(KeyboardType::ALPHABETIC)); + } +}; + +TEST_F(KeyboardInputMapperUnitTest_AlphabeticKeyboard_WakeFlagDisabled, WakeBehavior) { + // For internal alphabetic devices, keys will not trigger wake when flag is + // disabled. + + addKeyByEvdevCode(KEY_A, AKEYCODE_A); + addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME); + addKeyByEvdevCode(KEY_PLAYPAUSE, AKEYCODE_MEDIA_PLAY_PAUSE); + + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_A, 1); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); + + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_A, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); + + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_HOME, 1); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); + + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_HOME, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); + + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_PLAYPAUSE, 1); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); + + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_PLAYPAUSE, 0); + EXPECT_THAT(argsList, ElementsAre(VariantWith<NotifyKeyArgs>(WithPolicyFlags(0U)))); } // --- KeyboardInputMapperTest --- @@ -730,28 +862,33 @@ protected: } const std::string UNIQUE_ID = "local:0"; - void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode, - int32_t originalKeyCode, int32_t rotatedKeyCode, + void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalEvdevCode, + int32_t rotatedKeyCode, ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID); + + void processKeyAndSync(InputMapper& mapper, nsecs_t when, nsecs_t readTime, int32_t code, + int32_t value) { + process(mapper, when, readTime, EV_KEY, code, value); + process(mapper, when, readTime, EV_SYN, SYN_REPORT, 0); + } }; void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper& mapper, - int32_t originalScanCode, int32_t originalKeyCode, - int32_t rotatedKeyCode, + int32_t originalEvdevCode, int32_t rotatedKeyCode, ui::LogicalDisplayId displayId) { NotifyKeyArgs args; - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 1); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, originalEvdevCode, 1); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); - ASSERT_EQ(originalScanCode, args.scanCode); + ASSERT_EQ(originalEvdevCode, args.scanCode); ASSERT_EQ(rotatedKeyCode, args.keyCode); ASSERT_EQ(displayId, args.displayId); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 0); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, originalEvdevCode, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); - ASSERT_EQ(originalScanCode, args.scanCode); + ASSERT_EQ(originalEvdevCode, args.scanCode); ASSERT_EQ(rotatedKeyCode, args.keyCode); ASSERT_EQ(displayId, args.displayId); } @@ -819,23 +956,19 @@ TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) { ASSERT_TRUE(device2->isEnabled()); // Test pad key events + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, DISPLAY_ID)); ASSERT_NO_FATAL_FAILURE( - testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, - AKEYCODE_DPAD_RIGHT, DISPLAY_ID)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN, - AKEYCODE_DPAD_DOWN, DISPLAY_ID)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT, - AKEYCODE_DPAD_LEFT, DISPLAY_ID)); + testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, newDisplayId)); + ASSERT_NO_FATAL_FAILURE( + testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, newDisplayId)); + ASSERT_NO_FATAL_FAILURE( + testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN, newDisplayId)); ASSERT_NO_FATAL_FAILURE( - testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, newDisplayId)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, - AKEYCODE_DPAD_RIGHT, newDisplayId)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN, - AKEYCODE_DPAD_DOWN, newDisplayId)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT, - AKEYCODE_DPAD_LEFT, newDisplayId)); + testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT, newDisplayId)); } TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleAfterReattach) { @@ -857,20 +990,20 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleAfterReattach) { ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL)); // Toggle caps lock on. - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_CAPSLOCK, 1); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_CAPSLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL)); ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState()); // Toggle num lock on. - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_NUMLOCK, 1); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_NUMLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML)); ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState()); // Toggle scroll lock on. - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_SCROLLLOCK, 1); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_SCROLLLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL)); ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState()); @@ -937,16 +1070,16 @@ TEST_F(KeyboardInputMapperTest, Process_ResetLockedModifierState) { ASSERT_EQ(AMETA_NONE, mapper.getMetaState()); // Toggle caps lock on. - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_CAPSLOCK, 1); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_CAPSLOCK, 0); // Toggle num lock on. - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_NUMLOCK, 1); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_NUMLOCK, 0); // Toggle scroll lock on. - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_SCROLLLOCK, 1); + processKeyAndSync(mapper, ARBITRARY_TIME, READ_TIME, KEY_SCROLLLOCK, 0); ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState()); mReader->resetLockedModifierState(); @@ -996,40 +1129,40 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) { ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); // Toggle num lock on and off. - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1); - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_NUMLOCK, 1); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_NUMLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML)); ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState()); ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState()); - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1); - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_NUMLOCK, 1); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_NUMLOCK, 0); ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML)); ASSERT_EQ(AMETA_NONE, mapper1.getMetaState()); ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); // Toggle caps lock on and off. - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1); - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_CAPSLOCK, 1); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_CAPSLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL)); ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState()); ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState()); - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1); - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_CAPSLOCK, 1); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_CAPSLOCK, 0); ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL)); ASSERT_EQ(AMETA_NONE, mapper1.getMetaState()); ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); // Toggle scroll lock on and off. - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1); - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_SCROLLLOCK, 1); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_SCROLLLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL)); ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState()); ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState()); - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1); - process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_SCROLLLOCK, 1); + processKeyAndSync(mapper1, ARBITRARY_TIME, READ_TIME, KEY_SCROLLLOCK, 0); ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL)); ASSERT_EQ(AMETA_NONE, mapper1.getMetaState()); ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); @@ -1048,10 +1181,10 @@ TEST_F(KeyboardInputMapperTest, UsesSharedKeyboardSource) { KeyboardInputMapper& keyboardMapper = constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD); - process(keyboardMapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 1); + processKeyAndSync(keyboardMapper, ARBITRARY_TIME, 0, KEY_HOME, 1); ASSERT_NO_FATAL_FAILURE( mFakeListener->assertNotifyKeyWasCalled(WithSource(AINPUT_SOURCE_KEYBOARD))); - process(keyboardMapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 0); + processKeyAndSync(keyboardMapper, ARBITRARY_TIME, 0, KEY_HOME, 0); ASSERT_NO_FATAL_FAILURE( mFakeListener->assertNotifyKeyWasCalled(WithSource(AINPUT_SOURCE_KEYBOARD))); @@ -1059,10 +1192,10 @@ TEST_F(KeyboardInputMapperTest, UsesSharedKeyboardSource) { KeyboardInputMapper& dpadMapper = constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_DPAD); for (auto* mapper : {&keyboardMapper, &dpadMapper}) { - process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 1); + processKeyAndSync(*mapper, ARBITRARY_TIME, 0, KEY_HOME, 1); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled( WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD))); - process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 0); + processKeyAndSync(*mapper, ARBITRARY_TIME, 0, KEY_HOME, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled( WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD))); } @@ -1071,10 +1204,10 @@ TEST_F(KeyboardInputMapperTest, UsesSharedKeyboardSource) { KeyboardInputMapper& gamepadMapper = constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_GAMEPAD); for (auto* mapper : {&keyboardMapper, &dpadMapper, &gamepadMapper}) { - process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 1); + processKeyAndSync(*mapper, ARBITRARY_TIME, 0, KEY_HOME, 1); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled( WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD))); - process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 0); + processKeyAndSync(*mapper, ARBITRARY_TIME, 0, KEY_HOME, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled( WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD))); } @@ -1085,10 +1218,9 @@ TEST_F(KeyboardInputMapperTest, UsesSharedKeyboardSource) { class KeyboardInputMapperTest_ExternalAlphabeticDevice : public KeyboardInputMapperUnitTest { protected: void SetUp() override { - InputMapperUnitTest::SetUp(); + InputMapperUnitTest::SetUp(/*bus=*/0, /*isExternal=*/true); ON_CALL((*mDevice), getSources).WillByDefault(Return(AINPUT_SOURCE_KEYBOARD)); ON_CALL((*mDevice), getKeyboardType).WillByDefault(Return(KeyboardType::ALPHABETIC)); - ON_CALL((*mDevice), isExternal).WillByDefault(Return(true)); EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID)) .WillRepeatedly(Return(InputDeviceClass::KEYBOARD | InputDeviceClass::ALPHAKEY | InputDeviceClass::EXTERNAL)); @@ -1102,10 +1234,9 @@ protected: class KeyboardInputMapperTest_ExternalNonAlphabeticDevice : public KeyboardInputMapperUnitTest { protected: void SetUp() override { - InputMapperUnitTest::SetUp(); + InputMapperUnitTest::SetUp(/*bus=*/0, /*isExternal=*/true); ON_CALL((*mDevice), getSources).WillByDefault(Return(AINPUT_SOURCE_KEYBOARD)); ON_CALL((*mDevice), getKeyboardType).WillByDefault(Return(KeyboardType::NON_ALPHABETIC)); - ON_CALL((*mDevice), isExternal).WillByDefault(Return(true)); EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID)) .WillRepeatedly(Return(InputDeviceClass::KEYBOARD | InputDeviceClass::EXTERNAL)); mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration, @@ -1121,22 +1252,22 @@ TEST_F(KeyboardInputMapperTest_ExternalAlphabeticDevice, WakeBehavior_Alphabetic addKeyByEvdevCode(KEY_PLAY, AKEYCODE_MEDIA_PLAY); addKeyByEvdevCode(KEY_PLAYPAUSE, AKEYCODE_MEDIA_PLAY_PAUSE, POLICY_FLAG_WAKE); - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_HOME, 1); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_HOME, 0); ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAY, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_PLAY, 1); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAY, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_PLAY, 0); ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAYPAUSE, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_PLAYPAUSE, 1); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAYPAUSE, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_PLAYPAUSE, 0); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); } @@ -1147,16 +1278,16 @@ TEST_F(KeyboardInputMapperTest_ExternalNonAlphabeticDevice, WakeBehavior_NonAlph addKeyByEvdevCode(KEY_PLAY, AKEYCODE_MEDIA_PLAY); addKeyByEvdevCode(KEY_PLAYPAUSE, AKEYCODE_MEDIA_PLAY_PAUSE, POLICY_FLAG_WAKE); - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAY, 1); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_PLAY, 1); ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAY, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_PLAY, 0); ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAYPAUSE, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_PLAYPAUSE, 1); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAYPAUSE, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_PLAYPAUSE, 0); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); } @@ -1171,22 +1302,22 @@ TEST_F(KeyboardInputMapperTest_ExternalAlphabeticDevice, DoNotWakeByDefaultBehav mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration, AINPUT_SOURCE_KEYBOARD); - std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1); + std::list<NotifyArgs> argsList = processKeyAndSync(ARBITRARY_TIME, KEY_HOME, 1); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_HOME, 0); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_DOWN, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_DOWN, 1); ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_DOWN, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_DOWN, 0); ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAY, 1); + argsList = processKeyAndSync(ARBITRARY_TIME, KEY_PLAY, 1); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); - argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAY, 0); + argsList = processKeyAndSync(ARBITRARY_TIME + 1, KEY_PLAY, 0); ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags); } diff --git a/services/inputflinger/tests/LatencyTracker_test.cpp b/services/inputflinger/tests/LatencyTracker_test.cpp index ca0f1e8999..d8c5eac3c4 100644 --- a/services/inputflinger/tests/LatencyTracker_test.cpp +++ b/services/inputflinger/tests/LatencyTracker_test.cpp @@ -57,6 +57,7 @@ void setDefaultInputDeviceInfo(LatencyTracker& tracker) { } const auto FIRST_TOUCH_POINTER = PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(200); +const auto FIRST_MOUSE_POINTER = PointerBuilder(/*id=*/1, ToolType::MOUSE); /** * This is a convenience method for comparing timelines that also prints the difference between @@ -79,8 +80,9 @@ bool timelinesAreEqual(const InputEventTimeline& received, const InputEventTimel << "Received timeline with productId=" << received.productId << " instead of expected productId=" << expected.productId; LOG_IF(ERROR, expected.sources != received.sources) - << "Received timeline with sources=" << dumpSet(received.sources, ftl::enum_string) - << " instead of expected sources=" << dumpSet(expected.sources, ftl::enum_string); + << "Received timeline with sources=" + << dumpContainer(received.sources, ftl::enum_string) + << " instead of expected sources=" << dumpContainer(expected.sources, ftl::enum_string); LOG_IF(ERROR, expected.inputEventActionType != received.inputEventActionType) << "Received timeline with inputEventActionType=" << ftl::enum_string(received.inputEventActionType) @@ -491,8 +493,13 @@ TEST_F(LatencyTrackerTest, TrackListenerCheck_InputEventActionTypeFieldInputEven /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::BUTTONS}, InputEventActionType::KEY); - InputEventTimeline unknownTimeline( + InputEventTimeline motionScrollTimeline( /*eventTime*/ 12, /*readTime*/ 13, + /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::MOUSE}, + InputEventActionType::MOTION_ACTION_SCROLL); + + InputEventTimeline unknownTimeline( + /*eventTime*/ 14, /*readTime*/ 15, /*vendorId*/ 0, /*productId*/ 0, {InputDeviceUsageSource::TOUCHSCREEN}, InputEventActionType::UNKNOWN_INPUT_EVENT); @@ -529,8 +536,15 @@ TEST_F(LatencyTrackerTest, TrackListenerCheck_InputEventActionTypeFieldInputEven .readTime(keyUpTimeline.readTime) .deviceId(DEVICE_ID) .build()); + mTracker->trackListener( + MotionArgsBuilder(AMOTION_EVENT_ACTION_SCROLL, AINPUT_SOURCE_MOUSE, inputEventId + 5) + .eventTime(motionScrollTimeline.eventTime) + .readTime(motionScrollTimeline.readTime) + .deviceId(DEVICE_ID) + .pointer(FIRST_MOUSE_POINTER) + .build()); mTracker->trackListener(MotionArgsBuilder(AMOTION_EVENT_ACTION_POINTER_DOWN, - AINPUT_SOURCE_TOUCHSCREEN, inputEventId + 5) + AINPUT_SOURCE_TOUCHSCREEN, inputEventId + 6) .eventTime(unknownTimeline.eventTime) .readTime(unknownTimeline.readTime) .deviceId(DEVICE_ID) @@ -541,7 +555,8 @@ TEST_F(LatencyTrackerTest, TrackListenerCheck_InputEventActionTypeFieldInputEven std::vector<InputEventTimeline> expectedTimelines = {motionDownTimeline, motionMoveTimeline, motionUpTimeline, keyDownTimeline, - keyUpTimeline, unknownTimeline}; + keyUpTimeline, motionScrollTimeline, + unknownTimeline}; assertReceivedTimelines(expectedTimelines); } diff --git a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp index 9a6b266b21..cc3d1239ce 100644 --- a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp +++ b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp @@ -23,6 +23,7 @@ #include "InputMapperTest.h" #include "InterfaceMocks.h" +#include "ScopedFlagOverride.h" #include "TestEventMatchers.h" #define TAG "MultiTouchpadInputMapperUnit_test" @@ -30,29 +31,44 @@ namespace android { using testing::_; +using testing::AllOf; using testing::IsEmpty; using testing::Return; using testing::SetArgPointee; using testing::VariantWith; -static constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT; -static constexpr int32_t DISPLAY_WIDTH = 480; -static constexpr int32_t DISPLAY_HEIGHT = 800; -static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified -static constexpr int32_t SLOT_COUNT = 5; +namespace { -static constexpr int32_t ACTION_POINTER_0_UP = +constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT; +constexpr ui::LogicalDisplayId SECOND_DISPLAY_ID = ui::LogicalDisplayId{DISPLAY_ID.val() + 1}; +constexpr int32_t DISPLAY_WIDTH = 480; +constexpr int32_t DISPLAY_HEIGHT = 800; +constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified +constexpr int32_t SLOT_COUNT = 5; + +constexpr int32_t ACTION_DOWN = AMOTION_EVENT_ACTION_DOWN; +constexpr int32_t ACTION_CANCEL = AMOTION_EVENT_ACTION_CANCEL; +constexpr int32_t ACTION_POINTER_0_UP = AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); -static constexpr int32_t ACTION_POINTER_1_DOWN = +constexpr int32_t ACTION_POINTER_1_DOWN = AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); +template <typename... Args> +void assertNotifyArgs(const std::list<NotifyArgs>& args, Args... matchers) { + ASSERT_THAT(args, ElementsAre(matchers...)) + << "Got instead: " << dumpContainer(args, streamableToString); +} + +} // namespace + /** * Unit tests for MultiTouchInputMapper. */ class MultiTouchInputMapperUnitTest : public InputMapperUnitTest { protected: - void SetUp() override { - InputMapperUnitTest::SetUp(); + void SetUp() override { SetUp(/*bus=*/0, /*isExternal=*/false); } + void SetUp(int bus, bool isExternal) override { + InputMapperUnitTest::SetUp(bus, isExternal); // Present scan codes expectScanCodes(/*present=*/true, @@ -81,6 +97,17 @@ protected: EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, _)).WillRepeatedly(Return(false)); EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, INPUT_PROP_DIRECT)) .WillRepeatedly(Return(true)); + // The following EXPECT_CALL lines are not load-bearing, but without them gtest prints + // warnings about "uninteresting mocked call", which are distracting when developing the + // tests because this text is interleaved with logs of interest. + EXPECT_CALL(mMockEventHub, getVirtualKeyDefinitions(EVENTHUB_ID, _)) + .WillRepeatedly(Return()); + EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, _)) + .WillRepeatedly(testing::Return(false)); + EXPECT_CALL(mMockEventHub, getVideoFrames(EVENTHUB_ID)) + .WillRepeatedly(testing::Return(std::vector<TouchVideoFrame>{})); + EXPECT_CALL(mMockInputReaderContext, getExternalStylusDevices(_)).WillRepeatedly(Return()); + EXPECT_CALL(mMockInputReaderContext, getGlobalMetaState()).WillRepeatedly(Return(0)); // Axes that the device has setupAxis(ABS_MT_SLOT, /*valid=*/true, /*min=*/0, /*max=*/SLOT_COUNT - 1, /*resolution=*/0); @@ -106,9 +133,10 @@ protected: mockSlotValues({}); mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID); - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, "local:0", NO_PORT, - ViewportType::INTERNAL); + DisplayViewport internalViewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(internalViewport); mMapper = createInputMapper<MultiTouchInputMapper>(*mDeviceContext, mFakePolicy->getReaderConfiguration()); } @@ -147,24 +175,97 @@ protected: }); } - std::list<NotifyArgs> processPosition(int32_t x, int32_t y) { + [[nodiscard]] std::list<NotifyArgs> processPosition(int32_t x, int32_t y) { std::list<NotifyArgs> args; args += process(EV_ABS, ABS_MT_POSITION_X, x); args += process(EV_ABS, ABS_MT_POSITION_Y, y); return args; } - std::list<NotifyArgs> processId(int32_t id) { return process(EV_ABS, ABS_MT_TRACKING_ID, id); } + [[nodiscard]] std::list<NotifyArgs> processId(int32_t id) { + return process(EV_ABS, ABS_MT_TRACKING_ID, id); + } - std::list<NotifyArgs> processKey(int32_t code, int32_t value) { + [[nodiscard]] std::list<NotifyArgs> processKey(int32_t code, int32_t value) { return process(EV_KEY, code, value); } - std::list<NotifyArgs> processSlot(int32_t slot) { return process(EV_ABS, ABS_MT_SLOT, slot); } + [[nodiscard]] std::list<NotifyArgs> processSlot(int32_t slot) { + return process(EV_ABS, ABS_MT_SLOT, slot); + } - std::list<NotifyArgs> processSync() { return process(EV_SYN, SYN_REPORT, 0); } + [[nodiscard]] std::list<NotifyArgs> processSync() { return process(EV_SYN, SYN_REPORT, 0); } }; +/** + * While a gesture is active, change the display that the device is associated with. Make sure that + * the CANCEL event that's generated has the display id of the original DOWN event, rather than the + * new display id. + */ +TEST_F(MultiTouchInputMapperUnitTest, ChangeAssociatedDisplayIdWhenTouchIsActive) { + std::list<NotifyArgs> args; + + // Add a second viewport that later will be associated with our device. + DisplayViewport secondViewport = + createViewport(SECOND_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, "local:1", NO_PORT, ViewportType::EXTERNAL); + mFakePolicy->addDisplayViewport(secondViewport); + std::optional<DisplayViewport> firstViewport = + mFakePolicy->getDisplayViewportByUniqueId("local:0"); + + // InputReaderConfiguration contains information about how devices are associated with displays. + // The mapper receives this information. However, it doesn't actually parse it - that's done by + // InputDevice. The mapper asks InputDevice about the associated viewport, so that's what we + // need to mock here to simulate association. This abstraction is confusing and should be + // refactored. + + // Start with the first viewport + ON_CALL((*mDevice), getAssociatedViewport).WillByDefault(Return(firstViewport)); + args += mMapper->reconfigure(systemTime(SYSTEM_TIME_MONOTONIC), mReaderConfiguration, + InputReaderConfiguration::Change::DISPLAY_INFO); + + int32_t x1 = 100, y1 = 125; + args += processKey(BTN_TOUCH, 1); + args += processPosition(x1, y1); + args += processId(1); + args += processSync(); + ASSERT_THAT(args, + ElementsAre(VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(ACTION_DOWN), WithDisplayId(DISPLAY_ID))))); + args.clear(); + + // Now associate with the second viewport, and reconfigure. + ON_CALL((*mDevice), getAssociatedViewport).WillByDefault(Return(secondViewport)); + args += mMapper->reconfigure(systemTime(SYSTEM_TIME_MONOTONIC), mReaderConfiguration, + InputReaderConfiguration::Change::DISPLAY_INFO); + assertNotifyArgs(args, + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(DISPLAY_ID))), + VariantWith<NotifyDeviceResetArgs>(WithDeviceId(DEVICE_ID))); + + // The remainder of the gesture is ignored + // Move. + x1 += 10; + y1 += 15; + args = processPosition(x1, y1); + args += processSync(); + // Up + args += processKey(BTN_TOUCH, 0); + args += processId(-1); + args += processSync(); + + ASSERT_THAT(args, IsEmpty()); + + // New touch is delivered with the new display id. + args += processId(2); + args += processKey(BTN_TOUCH, 1); + args += processPosition(x1 + 20, y1 + 40); + args += processSync(); + assertNotifyArgs(args, + VariantWith<NotifyMotionArgs>(AllOf(WithMotionAction(ACTION_DOWN), + WithDisplayId(SECOND_DISPLAY_ID)))); +} + // This test simulates a multi-finger gesture with unexpected reset in between. This might happen // due to buffer overflow and device with report a SYN_DROPPED. In this case we expect mapper to be // reset, MT slot state to be re-populated and the gesture should be cancelled and restarted. @@ -174,7 +275,7 @@ TEST_F(MultiTouchInputMapperUnitTest, MultiFingerGestureWithUnexpectedReset) { // Two fingers down at once. constexpr int32_t FIRST_TRACKING_ID = 1, SECOND_TRACKING_ID = 2; int32_t x1 = 100, y1 = 125, x2 = 200, y2 = 225; - processKey(BTN_TOUCH, 1); + args += processKey(BTN_TOUCH, 1); args += processPosition(x1, y1); args += processId(FIRST_TRACKING_ID); args += processSlot(1); @@ -182,7 +283,7 @@ TEST_F(MultiTouchInputMapperUnitTest, MultiFingerGestureWithUnexpectedReset) { args += processId(SECOND_TRACKING_ID); ASSERT_THAT(args, IsEmpty()); - args = processSync(); + args += processSync(); ASSERT_THAT(args, ElementsAre(VariantWith<NotifyMotionArgs>( WithMotionAction(AMOTION_EVENT_ACTION_DOWN)), @@ -255,8 +356,8 @@ TEST_F(MultiTouchInputMapperUnitTest, MultiFingerGestureWithUnexpectedReset) { ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_POINTER_0_UP)))); // Second finger up. - processKey(BTN_TOUCH, 0); - args = processSlot(1); + args = processKey(BTN_TOUCH, 0); + args += processSlot(1); args += processId(-1); ASSERT_THAT(args, IsEmpty()); @@ -266,4 +367,146 @@ TEST_F(MultiTouchInputMapperUnitTest, MultiFingerGestureWithUnexpectedReset) { VariantWith<NotifyMotionArgs>(WithMotionAction(AMOTION_EVENT_ACTION_UP)))); } +class ExternalMultiTouchInputMapperTest : public MultiTouchInputMapperUnitTest { +protected: + void SetUp() override { MultiTouchInputMapperUnitTest::SetUp(/*bus=*/0, /*isExternal=*/true); } +}; + +/** + * Expect fallback to internal viewport if device is external and external viewport is not present. + */ +TEST_F(ExternalMultiTouchInputMapperTest, Viewports_Fallback) { + std::list<NotifyArgs> args; + + // Expect the event to be sent to the internal viewport, + // because an external viewport is not present. + args += processKey(BTN_TOUCH, 1); + args += processId(1); + args += processPosition(100, 200); + args += processSync(); + + assertNotifyArgs(args, + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(ACTION_DOWN), WithDisplayId(DISPLAY_ID)))); + + // Expect the event to be sent to the external viewport if it is present. + DisplayViewport externalViewport = + createViewport(SECOND_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, "local:1", NO_PORT, ViewportType::EXTERNAL); + mFakePolicy->addDisplayViewport(externalViewport); + std::optional<DisplayViewport> internalViewport = + mFakePolicy->getDisplayViewportByUniqueId("local:0"); + mReaderConfiguration.setDisplayViewports({*internalViewport, externalViewport}); + args = mMapper->reconfigure(systemTime(SYSTEM_TIME_MONOTONIC), mReaderConfiguration, + InputReaderConfiguration::Change::DISPLAY_INFO); + + assertNotifyArgs(args, + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(DISPLAY_ID))), + VariantWith<NotifyDeviceResetArgs>(WithDeviceId(DEVICE_ID))); + // Lift up the old pointer. + args = processKey(BTN_TOUCH, 0); + args += processId(-1); + args += processSync(); + + // Send new pointer + args += processKey(BTN_TOUCH, 1); + args += processId(2); + args += processPosition(111, 211); + args += processSync(); + assertNotifyArgs(args, + VariantWith<NotifyMotionArgs>(AllOf(WithMotionAction(ACTION_DOWN), + WithDisplayId(SECOND_DISPLAY_ID)))); +} + +class MultiTouchInputMapperPointerModeUnitTest : public MultiTouchInputMapperUnitTest { +protected: + void SetUp() override { + MultiTouchInputMapperUnitTest::SetUp(); + + // TouchInputMapper goes into POINTER mode whenever INPUT_PROP_DIRECT is not set. + EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, INPUT_PROP_DIRECT)) + .WillRepeatedly(Return(false)); + + mMapper = createInputMapper<MultiTouchInputMapper>(*mDeviceContext, + mFakePolicy->getReaderConfiguration()); + } +}; + +TEST_F(MultiTouchInputMapperPointerModeUnitTest, MouseToolOnlyDownWhenMouseButtonsAreDown) { + SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, true); + + std::list<NotifyArgs> args; + + // Set the tool type to mouse. + args += processKey(BTN_TOOL_MOUSE, 1); + + args += processPosition(100, 100); + args += processId(1); + ASSERT_THAT(args, IsEmpty()); + + args = processSync(); + ASSERT_THAT(args, + ElementsAre(VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER), + WithToolType(ToolType::MOUSE))), + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), + WithToolType(ToolType::MOUSE))))); + + // Setting BTN_TOUCH does not make a mouse pointer go down. + args = processKey(BTN_TOUCH, 1); + args += processSync(); + ASSERT_THAT(args, + ElementsAre(VariantWith<NotifyMotionArgs>( + WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE)))); + + // The mouse button is pressed, so the mouse goes down. + args = processKey(BTN_MOUSE, 1); + args += processSync(); + ASSERT_THAT(args, + ElementsAre(VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT), + WithToolType(ToolType::MOUSE))), + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), + WithToolType(ToolType::MOUSE), + WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY))), + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS), + WithToolType(ToolType::MOUSE), + WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), + WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY))))); + + // The mouse button is released, so the mouse starts hovering. + args = processKey(BTN_MOUSE, 0); + args += processSync(); + ASSERT_THAT(args, + ElementsAre(VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), + WithButtonState(0), WithToolType(ToolType::MOUSE), + WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY))), + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), + WithToolType(ToolType::MOUSE), WithButtonState(0))), + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER), + WithToolType(ToolType::MOUSE))), + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), + WithToolType(ToolType::MOUSE))))); + + // Change the tool type so that it is no longer a mouse. + // The default tool type is finger, and the finger is already down. + args = processKey(BTN_TOOL_MOUSE, 0); + args += processSync(); + ASSERT_THAT(args, + ElementsAre(VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT), + WithToolType(ToolType::MOUSE))), + VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), + WithToolType(ToolType::FINGER))))); +} + } // namespace android diff --git a/services/inputflinger/tests/PointerChoreographer_test.cpp b/services/inputflinger/tests/PointerChoreographer_test.cpp index 1ca2998f6b..2b469c5645 100644 --- a/services/inputflinger/tests/PointerChoreographer_test.cpp +++ b/services/inputflinger/tests/PointerChoreographer_test.cpp @@ -24,6 +24,7 @@ #include "FakePointerController.h" #include "InterfaceMocks.h" #include "NotifyArgsBuilders.h" +#include "ScopedFlagOverride.h" #include "TestEventMatchers.h" #include "TestInputListener.h" @@ -114,6 +115,10 @@ TestPointerChoreographer::TestPointerChoreographer( }) {} class PointerChoreographerTest : public testing::Test { +public: + static constexpr int DENSITY_MEDIUM = 160; + static constexpr int DENSITY_HIGH = 320; + protected: TestInputListener mTestListener; sp<gui::WindowInfosListener> mRegisteredWindowInfoListener; @@ -124,9 +129,6 @@ protected: mInjectedInitialWindowInfos}; void SetUp() override { - // flag overrides - input_flags::hide_pointer_indicators_for_secure_windows(true); - ON_CALL(mMockPolicy, createPointerController).WillByDefault([this](ControllerType type) { std::shared_ptr<FakePointerController> pc = std::make_shared<FakePointerController>(); EXPECT_FALSE(pc->isPointerShown()); @@ -140,6 +142,22 @@ protected: }); } + void setDefaultMouseDisplayId(ui::LogicalDisplayId displayId) { + if (input_flags::connected_displays_cursor()) { + // setDefaultMouseDisplayId is no-op if connected displays are enabled, mouse display is + // set based on primary display of the topology. + // Setting topology with the primary display should have same effect as calling + // setDefaultMouseDisplayId without topology. + // For this reason in tests we mock this behavior by creating topology with a single + // display. + mChoreographer.setDisplayTopology({.primaryDisplayId = displayId, + .graph{{displayId, {}}}, + .displaysDensity = {{displayId, DENSITY_MEDIUM}}}); + } else { + mChoreographer.setDefaultMouseDisplayId(displayId); + } + } + std::shared_ptr<FakePointerController> assertPointerControllerCreated( ControllerType expectedType) { EXPECT_FALSE(mCreatedControllers.empty()) << "No PointerController was created"; @@ -292,7 +310,7 @@ TEST_F(PointerChoreographerTest, WhenViewportSetLaterSetsViewportForAssociatedMo TEST_F(PointerChoreographerTest, SetsDefaultMouseViewportForPointerController) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); // For a mouse event without a target display, default viewport should be set for // the PointerController. @@ -309,7 +327,7 @@ TEST_F(PointerChoreographerTest, WhenDefaultMouseDisplayChangesSetsDefaultMouseViewportForPointerController) { // Set one display as a default mouse display and emit mouse event to create PointerController. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID, ANOTHER_DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -320,7 +338,7 @@ TEST_F(PointerChoreographerTest, // Change default mouse display. Existing PointerController should be removed and a new one // should be created. - mChoreographer.setDefaultMouseDisplayId(ANOTHER_DISPLAY_ID); + setDefaultMouseDisplayId(ANOTHER_DISPLAY_ID); assertPointerControllerRemoved(firstDisplayPc); auto secondDisplayPc = assertPointerControllerCreated(ControllerType::MOUSE); @@ -329,7 +347,7 @@ TEST_F(PointerChoreographerTest, } TEST_F(PointerChoreographerTest, CallsNotifyPointerDisplayIdChanged) { - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, @@ -340,8 +358,19 @@ TEST_F(PointerChoreographerTest, CallsNotifyPointerDisplayIdChanged) { assertPointerDisplayIdNotified(DISPLAY_ID); } +TEST_F(PointerChoreographerTest, NoDefaultMouseSetFallbackToDefaultDisplayId) { + mChoreographer.setDisplayViewports(createViewports({ui::LogicalDisplayId::DEFAULT})); + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, + {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, + ui::LogicalDisplayId::INVALID)}}); + assertPointerControllerCreated(ControllerType::MOUSE); + + assertPointerDisplayIdNotified(ui::LogicalDisplayId::DEFAULT); +} + TEST_F(PointerChoreographerTest, WhenViewportIsSetLaterCallsNotifyPointerDisplayIdChanged) { - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -354,7 +383,7 @@ TEST_F(PointerChoreographerTest, WhenViewportIsSetLaterCallsNotifyPointerDisplay } TEST_F(PointerChoreographerTest, WhenMouseIsRemovedCallsNotifyPointerDisplayIdChanged) { - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, @@ -373,7 +402,7 @@ TEST_F(PointerChoreographerTest, WhenDefaultMouseDisplayChangesCallsNotifyPointe mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID, ANOTHER_DISPLAY_ID})); // Set one viewport as a default mouse display ID. - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -382,7 +411,7 @@ TEST_F(PointerChoreographerTest, WhenDefaultMouseDisplayChangesCallsNotifyPointe assertPointerDisplayIdNotified(DISPLAY_ID); // Set another viewport as a default mouse display ID. The mouse is moved to the other display. - mChoreographer.setDefaultMouseDisplayId(ANOTHER_DISPLAY_ID); + setDefaultMouseDisplayId(ANOTHER_DISPLAY_ID); assertPointerControllerRemoved(firstDisplayPc); assertPointerControllerCreated(ControllerType::MOUSE); @@ -391,7 +420,7 @@ TEST_F(PointerChoreographerTest, WhenDefaultMouseDisplayChangesCallsNotifyPointe TEST_F(PointerChoreographerTest, MouseMovesPointerAndReturnsNewArgs) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -421,7 +450,7 @@ TEST_F(PointerChoreographerTest, MouseMovesPointerAndReturnsNewArgs) { TEST_F(PointerChoreographerTest, AbsoluteMouseMovesPointerAndReturnsNewArgs) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -457,7 +486,7 @@ TEST_F(PointerChoreographerTest, AssociatedMouseMovesPointerOnAssociatedDisplayAndDoesNotMovePointerOnDefaultDisplay) { // Add two displays and set one to default. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID, ANOTHER_DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); // Add two devices, one unassociated and the other associated with non-default mouse display. mChoreographer.notifyInputDevicesChanged( @@ -496,7 +525,7 @@ TEST_F(PointerChoreographerTest, TEST_F(PointerChoreographerTest, DoesNotMovePointerForMouseRelativeSource) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -543,7 +572,7 @@ TEST_F(PointerChoreographerTest, DoesNotMovePointerForMouseRelativeSource) { TEST_F(PointerChoreographerTest, WhenPointerCaptureEnabledHidesPointer) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -562,7 +591,7 @@ TEST_F(PointerChoreographerTest, WhenPointerCaptureEnabledHidesPointer) { TEST_F(PointerChoreographerTest, MultipleMiceConnectionAndRemoval) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); // A mouse is connected, and the pointer is shown. mChoreographer.notifyInputDevicesChanged( @@ -599,7 +628,7 @@ TEST_F(PointerChoreographerTest, MultipleMiceConnectionAndRemoval) { TEST_F(PointerChoreographerTest, UnrelatedChangeDoesNotUnfadePointer) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -628,7 +657,7 @@ TEST_F(PointerChoreographerTest, UnrelatedChangeDoesNotUnfadePointer) { TEST_F(PointerChoreographerTest, DisabledMouseConnected) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); InputDeviceInfo mouseDeviceInfo = generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ui::LogicalDisplayId::INVALID); // Disable this mouse device. @@ -641,7 +670,7 @@ TEST_F(PointerChoreographerTest, DisabledMouseConnected) { TEST_F(PointerChoreographerTest, MouseDeviceDisableLater) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); InputDeviceInfo mouseDeviceInfo = generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ui::LogicalDisplayId::INVALID); @@ -660,7 +689,7 @@ TEST_F(PointerChoreographerTest, MouseDeviceDisableLater) { TEST_F(PointerChoreographerTest, MultipleEnabledAndDisabledMiceConnectionAndRemoval) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); InputDeviceInfo disabledMouseDeviceInfo = generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ui::LogicalDisplayId::INVALID); disabledMouseDeviceInfo.setEnabled(false); @@ -1008,6 +1037,34 @@ TEST_F(PointerChoreographerTest, ShowTouchesOverridesUnspecifiedStylusIcon) { pc->assertPointerIconSet(PointerIconStyle::TYPE_SPOT_HOVER); } +TEST_F(PointerChoreographerTest, StylusHoverEnterFadesMouseOnDisplay) { + // Make sure there are PointerControllers for a mouse and a stylus. + mChoreographer.setStylusPointerIconEnabled(true); + setDefaultMouseDisplayId(DISPLAY_ID); + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, + {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ui::LogicalDisplayId::INVALID), + generateTestDeviceInfo(SECOND_DEVICE_ID, AINPUT_SOURCE_STYLUS, DISPLAY_ID)}}); + mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); + mChoreographer.notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(MOUSE_POINTER) + .deviceId(DEVICE_ID) + .displayId(ui::LogicalDisplayId::INVALID) + .build()); + auto mousePc = assertPointerControllerCreated(ControllerType::MOUSE); + ASSERT_TRUE(mousePc->isPointerShown()); + + // Start hovering with a stylus. This should fade the mouse cursor. + mChoreographer.notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS) + .pointer(STYLUS_POINTER) + .deviceId(SECOND_DEVICE_ID) + .displayId(DISPLAY_ID) + .build()); + ASSERT_FALSE(mousePc->isPointerShown()); +} + using StylusFixtureParam = std::tuple</*name*/ std::string_view, /*source*/ uint32_t, ControllerType>; @@ -1378,7 +1435,7 @@ TEST_F(PointerChoreographerTest, WhenViewportSetLaterSetsViewportForAssociatedTo TEST_F(PointerChoreographerTest, SetsDefaultTouchpadViewportForPointerController) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); // For a touchpad event without a target display, default viewport should be set for // the PointerController. @@ -1394,7 +1451,7 @@ TEST_F(PointerChoreographerTest, WhenDefaultTouchpadDisplayChangesSetsDefaultTouchpadViewportForPointerController) { // Set one display as a default touchpad display and create PointerController. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID, ANOTHER_DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, @@ -1403,7 +1460,7 @@ TEST_F(PointerChoreographerTest, firstDisplayPc->assertViewportSet(DISPLAY_ID); // Change default mouse display. Existing PointerController should be removed. - mChoreographer.setDefaultMouseDisplayId(ANOTHER_DISPLAY_ID); + setDefaultMouseDisplayId(ANOTHER_DISPLAY_ID); assertPointerControllerRemoved(firstDisplayPc); auto secondDisplayPc = assertPointerControllerCreated(ControllerType::MOUSE); @@ -1411,7 +1468,7 @@ TEST_F(PointerChoreographerTest, } TEST_F(PointerChoreographerTest, TouchpadCallsNotifyPointerDisplayIdChanged) { - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, @@ -1423,7 +1480,7 @@ TEST_F(PointerChoreographerTest, TouchpadCallsNotifyPointerDisplayIdChanged) { } TEST_F(PointerChoreographerTest, WhenViewportIsSetLaterTouchpadCallsNotifyPointerDisplayIdChanged) { - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, @@ -1436,7 +1493,7 @@ TEST_F(PointerChoreographerTest, WhenViewportIsSetLaterTouchpadCallsNotifyPointe } TEST_F(PointerChoreographerTest, WhenTouchpadIsRemovedCallsNotifyPointerDisplayIdChanged) { - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, @@ -1456,7 +1513,7 @@ TEST_F(PointerChoreographerTest, mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID, ANOTHER_DISPLAY_ID})); // Set one viewport as a default mouse display ID. - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, @@ -1466,7 +1523,7 @@ TEST_F(PointerChoreographerTest, // Set another viewport as a default mouse display ID. ui::LogicalDisplayId::INVALID will be // notified before a touchpad event. - mChoreographer.setDefaultMouseDisplayId(ANOTHER_DISPLAY_ID); + setDefaultMouseDisplayId(ANOTHER_DISPLAY_ID); assertPointerControllerRemoved(firstDisplayPc); assertPointerControllerCreated(ControllerType::MOUSE); @@ -1475,7 +1532,7 @@ TEST_F(PointerChoreographerTest, TEST_F(PointerChoreographerTest, TouchpadMovesPointerAndReturnsNewArgs) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, @@ -1505,7 +1562,7 @@ TEST_F(PointerChoreographerTest, TouchpadMovesPointerAndReturnsNewArgs) { TEST_F(PointerChoreographerTest, TouchpadAddsPointerPositionToTheCoords) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, @@ -1582,7 +1639,7 @@ TEST_F(PointerChoreographerTest, AssociatedTouchpadMovesPointerOnAssociatedDisplayAndDoesNotMovePointerOnDefaultDisplay) { // Add two displays and set one to default. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID, ANOTHER_DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); // Add two devices, one unassociated and the other associated with non-default mouse display. mChoreographer.notifyInputDevicesChanged( @@ -1623,7 +1680,7 @@ TEST_F(PointerChoreographerTest, TEST_F(PointerChoreographerTest, DoesNotMovePointerForTouchpadSource) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, @@ -1660,7 +1717,7 @@ TEST_F(PointerChoreographerTest, DoesNotMovePointerForTouchpadSource) { TEST_F(PointerChoreographerTest, WhenPointerCaptureEnabledTouchpadHidesPointer) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, @@ -1680,7 +1737,7 @@ TEST_F(PointerChoreographerTest, WhenPointerCaptureEnabledTouchpadHidesPointer) TEST_F(PointerChoreographerTest, SetsPointerIconForMouse) { // Make sure there is a PointerController. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -1696,7 +1753,7 @@ TEST_F(PointerChoreographerTest, SetsPointerIconForMouse) { TEST_F(PointerChoreographerTest, DoesNotSetMousePointerIconForWrongDisplayId) { // Make sure there is a PointerController. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -1713,7 +1770,7 @@ TEST_F(PointerChoreographerTest, DoesNotSetMousePointerIconForWrongDisplayId) { TEST_F(PointerChoreographerTest, DoesNotSetPointerIconForWrongDeviceId) { // Make sure there is a PointerController. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -1730,7 +1787,7 @@ TEST_F(PointerChoreographerTest, DoesNotSetPointerIconForWrongDeviceId) { TEST_F(PointerChoreographerTest, SetsCustomPointerIconForMouse) { // Make sure there is a PointerController. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -1754,7 +1811,7 @@ TEST_F(PointerChoreographerTest, SetsCustomPointerIconForMouse) { TEST_F(PointerChoreographerTest, SetsPointerIconForMouseOnTwoDisplays) { // Make sure there are two PointerControllers on different displays. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID, ANOTHER_DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ui::LogicalDisplayId::INVALID), @@ -1776,6 +1833,89 @@ TEST_F(PointerChoreographerTest, SetsPointerIconForMouseOnTwoDisplays) { firstMousePc->assertPointerIconNotSet(); } +TEST_F(PointerChoreographerTest, A11yPointerMotionFilterMouse) { + mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); + setDefaultMouseDisplayId(DISPLAY_ID); + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, + {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, + ui::LogicalDisplayId::INVALID)}}); + auto pc = assertPointerControllerCreated(ControllerType::MOUSE); + ASSERT_EQ(DISPLAY_ID, pc->getDisplayId()); + + pc->setPosition(100, 200); + mChoreographer.setAccessibilityPointerMotionFilterEnabled(true); + + EXPECT_CALL(mMockPolicy, + filterPointerMotionForAccessibility(testing::Eq(vec2{100, 200}), + testing::Eq(vec2{10.f, 20.f}), + testing::Eq(DISPLAY_ID))) + .Times(1) + .WillOnce(testing::Return(vec2{4, 13})); + + mChoreographer.notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(MOUSE_POINTER) + .deviceId(DEVICE_ID) + .displayId(ui::LogicalDisplayId::INVALID) + .build()); + + // Cursor position is decided by filtered delta, but pointer coord's relative values are kept. + pc->assertPosition(104, 213); + mTestListener.assertNotifyMotionWasCalled(AllOf(WithCoords(104, 213), WithDisplayId(DISPLAY_ID), + WithCursorPosition(104, 213), + WithRelativeMotion(10, 20))); +} + +TEST_F(PointerChoreographerTest, A11yPointerMotionFilterTouchpad) { + mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); + setDefaultMouseDisplayId(DISPLAY_ID); + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, + {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, + ui::LogicalDisplayId::INVALID)}}); + auto pc = assertPointerControllerCreated(ControllerType::MOUSE); + ASSERT_EQ(DISPLAY_ID, pc->getDisplayId()); + + pc->setPosition(100, 200); + mChoreographer.setAccessibilityPointerMotionFilterEnabled(true); + + EXPECT_CALL(mMockPolicy, + filterPointerMotionForAccessibility(testing::Eq(vec2{100, 200}), + testing::Eq(vec2{10.f, 20.f}), + testing::Eq(DISPLAY_ID))) + .Times(1) + .WillOnce(testing::Return(vec2{4, 13})); + + mChoreographer.notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(TOUCHPAD_POINTER) + .deviceId(DEVICE_ID) + .displayId(ui::LogicalDisplayId::INVALID) + .build()); + + // Cursor position is decided by filtered delta, but pointer coord's relative values are kept. + pc->assertPosition(104, 213); + mTestListener.assertNotifyMotionWasCalled(AllOf(WithCoords(104, 213), WithDisplayId(DISPLAY_ID), + WithCursorPosition(104, 213), + WithRelativeMotion(10, 20))); +} + +TEST_F(PointerChoreographerTest, A11yPointerMotionFilterNotFilterTouch) { + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID)}}); + mChoreographer.setAccessibilityPointerMotionFilterEnabled(true); + + EXPECT_CALL(mMockPolicy, filterPointerMotionForAccessibility).Times(0); + + mChoreographer.notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(FIRST_TOUCH_POINTER) + .deviceId(DEVICE_ID) + .displayId(DISPLAY_ID) + .build()); +} + using SkipPointerScreenshotForPrivacySensitiveDisplaysFixtureParam = std::tuple<std::string_view /*name*/, uint32_t /*source*/, ControllerType, PointerBuilder, std::function<void(PointerChoreographer&)>, int32_t /*action*/>; @@ -1966,10 +2106,7 @@ TEST_P(SkipPointerScreenshotForPrivacySensitiveDisplaysTestFixture, pc->assertSkipScreenshotFlagNotChanged(); } -TEST_F_WITH_FLAGS( - PointerChoreographerTest, HidesPointerScreenshotForExistingPrivacySensitiveWindows, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags, - hide_pointer_indicators_for_secure_windows))) { +TEST_F(PointerChoreographerTest, HidesPointerScreenshotForExistingPrivacySensitiveWindows) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); // Add a first mouse device @@ -2127,7 +2264,7 @@ TEST_P(StylusTestFixture, SetsPointerIconForMouseAndStylus) { // Make sure there are PointerControllers for a mouse and a stylus. mChoreographer.setStylusPointerIconEnabled(true); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ui::LogicalDisplayId::INVALID), @@ -2162,7 +2299,7 @@ TEST_P(StylusTestFixture, SetsPointerIconForMouseAndStylus) { TEST_F(PointerChoreographerTest, SetPointerIconVisibilityHidesPointerOnDisplay) { // Make sure there are two PointerControllers on different displays. mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID, ANOTHER_DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ui::LogicalDisplayId::INVALID), @@ -2216,7 +2353,7 @@ TEST_F(PointerChoreographerTest, SetPointerIconVisibilityHidesPointerOnDisplay) TEST_F(PointerChoreographerTest, SetPointerIconVisibilityHidesPointerWhenDeviceConnected) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); // Hide the pointer on the display, and then connect the mouse. mChoreographer.setPointerIconVisibility(DISPLAY_ID, false); @@ -2233,7 +2370,7 @@ TEST_F(PointerChoreographerTest, SetPointerIconVisibilityHidesPointerWhenDeviceC TEST_F(PointerChoreographerTest, SetPointerIconVisibilityHidesPointerForTouchpad) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); // Hide the pointer on the display. mChoreographer.setPointerIconVisibility(DISPLAY_ID, false); @@ -2282,7 +2419,7 @@ TEST_P(StylusTestFixture, SetPointerIconVisibilityHidesPointerForStylus) { TEST_F(PointerChoreographerTest, DrawingTabletCanReportMouseEvent) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, @@ -2309,7 +2446,7 @@ TEST_F(PointerChoreographerTest, DrawingTabletCanReportMouseEvent) { TEST_F(PointerChoreographerTest, MultipleDrawingTabletsReportMouseEvents) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); // First drawing tablet is added mChoreographer.notifyInputDevicesChanged( @@ -2357,7 +2494,7 @@ TEST_F(PointerChoreographerTest, MultipleDrawingTabletsReportMouseEvents) { TEST_F(PointerChoreographerTest, MouseAndDrawingTabletReportMouseEvents) { mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); // Mouse and drawing tablet connected mChoreographer.notifyInputDevicesChanged( @@ -2601,15 +2738,29 @@ TEST_P(PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixture, TestMetaKeyCom metaKeyCombinationDoesNotHidePointer(*pc, AKEYCODE_A, AKEYCODE_META_RIGHT); } -using PointerChoreographerDisplayTopologyTestFixtureParam = +class PointerChoreographerDisplayTopologyTests : public PointerChoreographerTest { +protected: + DisplayViewport createViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height, + ui::Rotation orientation) { + DisplayViewport viewport; + viewport.displayId = displayId; + viewport.logicalRight = width; + viewport.logicalBottom = height; + viewport.orientation = orientation; + return viewport; + } +}; + +using PointerChoreographerDisplayTopologyCursorTestFixtureParam = std::tuple<std::string_view /*name*/, int32_t /*source device*/, ControllerType /*PointerController*/, ToolType /*pointer tool type*/, vec2 /*source position*/, vec2 /*hover move X/Y*/, ui::LogicalDisplayId /*destination display*/, vec2 /*destination position*/>; -class PointerChoreographerDisplayTopologyTestFixture - : public PointerChoreographerTest, - public testing::WithParamInterface<PointerChoreographerDisplayTopologyTestFixtureParam> { +class PointerChoreographerDisplayTopologyCursorTestFixture + : public PointerChoreographerDisplayTopologyTests, + public testing::WithParamInterface< + PointerChoreographerDisplayTopologyCursorTestFixtureParam> { public: static constexpr ui::LogicalDisplayId DISPLAY_CENTER_ID = ui::LogicalDisplayId{10}; static constexpr ui::LogicalDisplayId DISPLAY_TOP_ID = ui::LogicalDisplayId{20}; @@ -2617,12 +2768,10 @@ public: static constexpr ui::LogicalDisplayId DISPLAY_BOTTOM_ID = ui::LogicalDisplayId{40}; static constexpr ui::LogicalDisplayId DISPLAY_LEFT_ID = ui::LogicalDisplayId{50}; static constexpr ui::LogicalDisplayId DISPLAY_TOP_RIGHT_CORNER_ID = ui::LogicalDisplayId{60}; - - PointerChoreographerDisplayTopologyTestFixture() { - com::android::input::flags::connected_displays_cursor(true); - } + static constexpr ui::LogicalDisplayId DISPLAY_HIGH_DENSITY_ID = ui::LogicalDisplayId{70}; protected: + // Note: viewport size is in pixels and offsets in topology are in dp std::vector<DisplayViewport> mViewports{ createViewport(DISPLAY_CENTER_ID, /*width*/ 100, /*height*/ 100, ui::ROTATION_0), createViewport(DISPLAY_TOP_ID, /*width*/ 90, /*height*/ 90, ui::ROTATION_0), @@ -2631,44 +2780,46 @@ protected: createViewport(DISPLAY_LEFT_ID, /*width*/ 90, /*height*/ 90, ui::ROTATION_270), createViewport(DISPLAY_TOP_RIGHT_CORNER_ID, /*width*/ 90, /*height*/ 90, ui::ROTATION_0), + // Create a high density display size 100x100 dp i.e. 200x200 px + createViewport(DISPLAY_HIGH_DENSITY_ID, /*width*/ 200, /*height*/ 200, ui::ROTATION_0), }; - DisplayTopologyGraph mTopology{DISPLAY_CENTER_ID, - {{DISPLAY_CENTER_ID, - {{DISPLAY_TOP_ID, DisplayTopologyPosition::TOP, 10.0f}, - {DISPLAY_RIGHT_ID, DisplayTopologyPosition::RIGHT, 10.0f}, - {DISPLAY_BOTTOM_ID, DisplayTopologyPosition::BOTTOM, 10.0f}, - {DISPLAY_LEFT_ID, DisplayTopologyPosition::LEFT, 10.0f}, - {DISPLAY_TOP_RIGHT_CORNER_ID, DisplayTopologyPosition::RIGHT, - -90.0f}}}}}; - -private: - DisplayViewport createViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height, - ui::Rotation orientation) { - DisplayViewport viewport; - viewport.displayId = displayId; - viewport.logicalRight = width; - viewport.logicalBottom = height; - viewport.orientation = orientation; - return viewport; - } + DisplayTopologyGraph + mTopology{DISPLAY_CENTER_ID, + {{DISPLAY_CENTER_ID, + {{DISPLAY_TOP_ID, DisplayTopologyPosition::TOP, 50.0f}, + // Place a high density display on the left of DISPLAY_TOP_ID with 25 dp + // gap + {DISPLAY_HIGH_DENSITY_ID, DisplayTopologyPosition::TOP, -75.0f}, + {DISPLAY_RIGHT_ID, DisplayTopologyPosition::RIGHT, 10.0f}, + {DISPLAY_BOTTOM_ID, DisplayTopologyPosition::BOTTOM, 10.0f}, + {DISPLAY_LEFT_ID, DisplayTopologyPosition::LEFT, 10.0f}, + {DISPLAY_TOP_RIGHT_CORNER_ID, DisplayTopologyPosition::RIGHT, -90.0f}}}}, + {{DISPLAY_CENTER_ID, DENSITY_MEDIUM}, + {DISPLAY_TOP_ID, DENSITY_MEDIUM}, + {DISPLAY_RIGHT_ID, DENSITY_MEDIUM}, + {DISPLAY_BOTTOM_ID, DENSITY_MEDIUM}, + {DISPLAY_LEFT_ID, DENSITY_MEDIUM}, + {DISPLAY_TOP_RIGHT_CORNER_ID, DENSITY_MEDIUM}, + {DISPLAY_HIGH_DENSITY_ID, DENSITY_HIGH}}}; }; -TEST_P(PointerChoreographerDisplayTopologyTestFixture, PointerChoreographerDisplayTopologyTest) { +TEST_P(PointerChoreographerDisplayTopologyCursorTestFixture, + PointerChoreographerDisplayTopologyTest) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + const auto& [_, device, pointerControllerType, pointerToolType, initialPosition, hoverMove, destinationDisplay, destinationPosition] = GetParam(); mChoreographer.setDisplayViewports(mViewports); - mChoreographer.setDefaultMouseDisplayId( - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID); + setDefaultMouseDisplayId(DISPLAY_CENTER_ID); mChoreographer.setDisplayTopology(mTopology); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, device, ui::LogicalDisplayId::INVALID)}}); auto pc = assertPointerControllerCreated(pointerControllerType); - ASSERT_EQ(PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID, - pc->getDisplayId()); + ASSERT_EQ(DISPLAY_CENTER_ID, pc->getDisplayId()); // Set initial position of the PointerController. pc->setPosition(initialPosition.x, initialPosition.y); @@ -2700,84 +2851,320 @@ TEST_P(PointerChoreographerDisplayTopologyTestFixture, PointerChoreographerDispl } INSTANTIATE_TEST_SUITE_P( - PointerChoreographerTest, PointerChoreographerDisplayTopologyTestFixture, + PointerChoreographerTest, PointerChoreographerDisplayTopologyCursorTestFixture, testing::Values( // Note: Upon viewport transition cursor will be positioned at the boundary of the // destination, as we drop any unconsumed delta. - std::make_tuple("PrimaryDisplayIsDefault", AINPUT_SOURCE_MOUSE, - ControllerType::MOUSE, ToolType::MOUSE, - vec2(50, 50) /* initial x/y */, vec2(0, 0) /* delta x/y */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID, - vec2(50, 50) /* destination x/y */), - std::make_tuple("UnchangedDisplay", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE, - ToolType::MOUSE, vec2(50, 50) /* initial x/y */, - vec2(25, 25) /* delta x/y */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID, - vec2(75, 75) /* destination x/y */), - std::make_tuple("TransitionToRightDisplay", AINPUT_SOURCE_MOUSE, - ControllerType::MOUSE, ToolType::MOUSE, - vec2(50, 50) /* initial x/y */, vec2(100, 25) /* delta x/y */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_RIGHT_ID, - vec2(0, - 50 + 25 - 10) /* Left edge: (0, source + delta - offset) */), + std::make_tuple( + "PrimaryDisplayIsDefault", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE, + ToolType::MOUSE, vec2(50, 50) /* initial x/y */, vec2(0, 0) /* delta x/y */, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_CENTER_ID, + vec2(50, 50) /* destination x/y */), + std::make_tuple( + "UnchangedDisplay", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE, + ToolType::MOUSE, vec2(50, 50) /* initial x/y */, + vec2(25, 25) /* delta x/y */, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_CENTER_ID, + vec2(75, 75) /* destination x/y */), + std::make_tuple( + "TransitionToRightDisplay", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE, + ToolType::MOUSE, vec2(50, 50) /* initial x/y */, + vec2(100, 25) /* delta x/y */, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_RIGHT_ID, + vec2(0, 50 + 25 - 10) /* Left edge: (0, source + delta - offset) */), std::make_tuple( "TransitionToLeftDisplay", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE, ToolType::MOUSE, vec2(50, 50) /* initial x/y */, vec2(-100, 25) /* delta x/y */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_LEFT_ID, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_LEFT_ID, vec2(90, 50 + 25 - 10) /* Right edge: (width, source + delta - offset*/), - std::make_tuple("TransitionToTopDisplay", - AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, ControllerType::MOUSE, - ToolType::FINGER, vec2(50, 50) /* initial x/y */, - vec2(25, -100) /* delta x/y */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_TOP_ID, - vec2(50 + 25 - 10, - 90) /* Bottom edge: (source + delta - offset, height) */), - std::make_tuple("TransitionToBottomDisplay", - AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, ControllerType::MOUSE, - ToolType::FINGER, vec2(50, 50) /* initial x/y */, - vec2(25, 100) /* delta x/y */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_BOTTOM_ID, - vec2(50 + 25 - 10, 0) /* Top edge: (source + delta - offset, 0) */), - std::make_tuple("NoTransitionAtTopOffset", AINPUT_SOURCE_MOUSE, - ControllerType::MOUSE, ToolType::MOUSE, - vec2(5, 50) /* initial x/y */, vec2(0, -100) /* Move Up */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID, - vec2(5, 0) /* Top edge */), - std::make_tuple("NoTransitionAtRightOffset", AINPUT_SOURCE_MOUSE, - ControllerType::MOUSE, ToolType::MOUSE, - vec2(95, 5) /* initial x/y */, vec2(100, 0) /* Move Right */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID, - vec2(99, 5) /* Top edge */), - std::make_tuple("NoTransitionAtBottomOffset", + std::make_tuple( + "TransitionToTopDisplay", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, + ControllerType::MOUSE, ToolType::FINGER, vec2(50, 50) /* initial x/y */, + vec2(25, -100) /* delta x/y */, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_TOP_ID, + vec2(50 + 25 - 50, + 90) /* Bottom edge: (source + delta - offset, height) */), + std::make_tuple( + "TransitionToBottomDisplay", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, + ControllerType::MOUSE, ToolType::FINGER, vec2(50, 50) /* initial x/y */, + vec2(25, 100) /* delta x/y */, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_BOTTOM_ID, + vec2(50 + 25 - 10, 0) /* Top edge: (source + delta - offset, 0) */), + // move towards 25 dp gap between DISPLAY_HIGH_DENSITY_ID and DISPLAY_TOP_ID + std::make_tuple( + "NoTransitionAtTopOffset", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE, + ToolType::MOUSE, vec2(35, 50) /* initial x/y */, + vec2(0, -100) /* Move Up */, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_CENTER_ID, + vec2(35, 0) /* Top edge */), + std::make_tuple( + "NoTransitionAtRightOffset", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE, + ToolType::MOUSE, vec2(95, 5) /* initial x/y */, + vec2(100, 0) /* Move Right */, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_CENTER_ID, + vec2(99, 5) /* Top edge */), + std::make_tuple( + "NoTransitionAtBottomOffset", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, + ControllerType::MOUSE, ToolType::FINGER, vec2(5, 95) /* initial x/y */, + vec2(0, 100) /* Move Down */, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_CENTER_ID, + vec2(5, 99) /* Bottom edge */), + std::make_tuple( + "NoTransitionAtLeftOffset", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, + ControllerType::MOUSE, ToolType::FINGER, vec2(5, 5) /* initial x/y */, + vec2(-100, 0) /* Move Left */, + PointerChoreographerDisplayTopologyCursorTestFixture::DISPLAY_CENTER_ID, + vec2(0, 5) /* Left edge */), + std::make_tuple("TransitionAtTopRightCorner", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, ControllerType::MOUSE, - ToolType::FINGER, vec2(5, 95) /* initial x/y */, - vec2(0, 100) /* Move Down */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID, - vec2(5, 99) /* Bottom edge */), - std::make_tuple("NoTransitionAtLeftOffset", + ToolType::FINGER, vec2(95, 5) /* initial x/y */, + vec2(10, -10) /* Move diagonally to top right corner */, + PointerChoreographerDisplayTopologyCursorTestFixture:: + DISPLAY_TOP_RIGHT_CORNER_ID, + vec2(0, 90) /* bottom left corner */), + std::make_tuple("TransitionToHighDpDisplay", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, ControllerType::MOUSE, - ToolType::FINGER, vec2(5, 5) /* initial x/y */, - vec2(-100, 0) /* Move Left */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID, - vec2(0, 5) /* Left edge */), - std::make_tuple( - "TransitionAtTopRightCorner", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, - ControllerType::MOUSE, ToolType::FINGER, vec2(95, 5) /* initial x/y */, - vec2(10, -10) /* Move dignally to top right corner */, - PointerChoreographerDisplayTopologyTestFixture::DISPLAY_TOP_RIGHT_CORNER_ID, - vec2(0, 90) /* bottom left corner */)), - [](const testing::TestParamInfo<PointerChoreographerDisplayTopologyTestFixtureParam>& p) { - return std::string{std::get<0>(p.param)}; - }); + ToolType::MOUSE, vec2(20, 20) /* initial x/y */, + vec2(0, -50) /* delta x/y */, + PointerChoreographerDisplayTopologyCursorTestFixture:: + DISPLAY_HIGH_DENSITY_ID, + /* Bottom edge: ((source + delta - offset) * density, height) */ + vec2((20 + 0 + 75) * 2, 200))), + [](const testing::TestParamInfo<PointerChoreographerDisplayTopologyCursorTestFixtureParam>& + p) { return std::string{std::get<0>(p.param)}; }); + +class PointerChoreographerDisplayTopologyDefaultMouseDisplayTests + : public PointerChoreographerDisplayTopologyTests { +protected: + static constexpr ui::LogicalDisplayId FIRST_DISPLAY_ID = ui::LogicalDisplayId{10}; + static constexpr ui::LogicalDisplayId SECOND_DISPLAY_ID = ui::LogicalDisplayId{20}; + static constexpr ui::LogicalDisplayId THIRD_DISPLAY_ID = ui::LogicalDisplayId{30}; + + DisplayViewport createViewport(ui::LogicalDisplayId displayId) { + return PointerChoreographerDisplayTopologyTests::createViewport(displayId, /*width=*/100, + /*height=*/100, + ui::ROTATION_0); + } + + void setDisplayTopologyWithDisplays( + ui::LogicalDisplayId primaryDisplayId, + const std::vector<ui::LogicalDisplayId>& adjacentDisplays = {}) { + // Prepare a topology with all display connected from left to right. + ui::LogicalDisplayId previousDisplay = primaryDisplayId; + + std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>> + topologyGraph; + topologyGraph[primaryDisplayId] = {}; + + std::unordered_map<ui::LogicalDisplayId, int> displaysDensity; + displaysDensity[primaryDisplayId] = DENSITY_MEDIUM; + + for (ui::LogicalDisplayId adjacentDisplayId : adjacentDisplays) { + topologyGraph[previousDisplay].push_back({.displayId = adjacentDisplayId, + .position = DisplayTopologyPosition::RIGHT, + .offsetDp = 0.0f}); + topologyGraph[adjacentDisplayId].push_back({.displayId = previousDisplay, + .position = DisplayTopologyPosition::LEFT, + .offsetDp = 0.0f}); + + displaysDensity[adjacentDisplayId] = DENSITY_MEDIUM; + } + + mChoreographer.setDisplayTopology({primaryDisplayId, topologyGraph, displaysDensity}); + } +}; + +TEST_F(PointerChoreographerDisplayTopologyDefaultMouseDisplayTests, + UnrelatedTopologyUpdatesDoNotChangeCursorDisplay) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + + // Set first display as primary display and emit mouse event to create PointerController. + mChoreographer.setDisplayViewports({createViewport(FIRST_DISPLAY_ID)}); + setDisplayTopologyWithDisplays(/*primaryDisplayId=*/FIRST_DISPLAY_ID); + + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, + {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, + ui::LogicalDisplayId::INVALID)}}); + auto pc = assertPointerControllerCreated(ControllerType::MOUSE); + pc->assertViewportSet(FIRST_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); + + // Add another display keeping the primary display unchanged + mChoreographer.setDisplayViewports( + {createViewport(FIRST_DISPLAY_ID), createViewport(SECOND_DISPLAY_ID)}); + setDisplayTopologyWithDisplays(/*primaryDisplayId=*/FIRST_DISPLAY_ID, + /*adjacentDisplays=*/{SECOND_DISPLAY_ID}); + + assertPointerControllerNotCreated(); + pc->assertViewportSet(FIRST_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); + + // Move cursor to second display and add a third display + auto pointerBuilder = PointerBuilder(/*id=*/0, ToolType::MOUSE) + .axis(AMOTION_EVENT_AXIS_RELATIVE_X, /*x=*/100) + .axis(AMOTION_EVENT_AXIS_RELATIVE_Y, /*y=*/0); + mChoreographer.notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(pointerBuilder) + .deviceId(DEVICE_ID) + .displayId(ui::LogicalDisplayId::INVALID) + .build()); + + assertPointerControllerNotCreated(); + pc->assertViewportSet(SECOND_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); + + mChoreographer.setDisplayViewports({createViewport(FIRST_DISPLAY_ID), + createViewport(SECOND_DISPLAY_ID), + createViewport(THIRD_DISPLAY_ID)}); + setDisplayTopologyWithDisplays(/*primaryDisplayId=*/FIRST_DISPLAY_ID, /*adjacentDisplays=*/ + {SECOND_DISPLAY_ID, THIRD_DISPLAY_ID}); + + assertPointerControllerNotCreated(); + pc->assertViewportSet(SECOND_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); + + // Change the primary display to the third display + setDisplayTopologyWithDisplays(/*primaryDisplayId=*/THIRD_DISPLAY_ID, /*adjacentDisplays=*/ + {SECOND_DISPLAY_ID, THIRD_DISPLAY_ID}); + + assertPointerControllerNotCreated(); + pc->assertViewportSet(SECOND_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); +} + +TEST_F(PointerChoreographerDisplayTopologyDefaultMouseDisplayTests, + PrimaryDisplayIsFallbackOnPointerDisplayRemoved) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + + // Add two displays and move cursor to the secondary display + mChoreographer.setDisplayViewports( + {createViewport(FIRST_DISPLAY_ID), createViewport(SECOND_DISPLAY_ID)}); + setDisplayTopologyWithDisplays(/*primaryDisplayId=*/FIRST_DISPLAY_ID, + /*adjacentDisplays=*/{SECOND_DISPLAY_ID}); + + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, + {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, + ui::LogicalDisplayId::INVALID)}}); + auto pc = assertPointerControllerCreated(ControllerType::MOUSE); + pc->assertViewportSet(FIRST_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); + + auto pointerBuilder = PointerBuilder(/*id=*/0, ToolType::MOUSE) + .axis(AMOTION_EVENT_AXIS_RELATIVE_X, /*x=*/100) + .axis(AMOTION_EVENT_AXIS_RELATIVE_Y, /*y=*/0); + mChoreographer.notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(pointerBuilder) + .deviceId(DEVICE_ID) + .displayId(ui::LogicalDisplayId::INVALID) + .build()); + + assertPointerControllerNotCreated(); + pc->assertViewportSet(SECOND_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); + + // Remove the secondary display + mChoreographer.setDisplayViewports({createViewport(FIRST_DISPLAY_ID)}); + setDisplayTopologyWithDisplays(/*primaryDisplayId=*/FIRST_DISPLAY_ID); + + assertPointerControllerRemoved(pc); + pc = assertPointerControllerCreated(ControllerType::MOUSE); + pc->assertViewportSet(FIRST_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); +} + +TEST_F(PointerChoreographerDisplayTopologyDefaultMouseDisplayTests, + UsePrimaryDisplayIfAssociatedDisplayIsInTopology) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + SCOPED_FLAG_OVERRIDE(connected_displays_associated_display_cursor_bugfix, true); + + // Add two displays + mChoreographer.setDisplayViewports( + {createViewport(FIRST_DISPLAY_ID), createViewport(SECOND_DISPLAY_ID)}); + setDisplayTopologyWithDisplays(/*primaryDisplayId=*/SECOND_DISPLAY_ID, + /*adjacentDisplays=*/{FIRST_DISPLAY_ID}); + + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, FIRST_DISPLAY_ID)}}); + + auto pc = assertPointerControllerCreated(ControllerType::MOUSE); + pc->assertViewportSet(SECOND_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); +} + +TEST_F(PointerChoreographerDisplayTopologyDefaultMouseDisplayTests, + AllowCrossingDisplayEvenWithAssociatedDisplaySet) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + SCOPED_FLAG_OVERRIDE(connected_displays_associated_display_cursor_bugfix, true); + + // Add two displays + mChoreographer.setDisplayViewports( + {createViewport(FIRST_DISPLAY_ID), createViewport(SECOND_DISPLAY_ID)}); + setDisplayTopologyWithDisplays(/*primaryDisplayId=*/FIRST_DISPLAY_ID, + /*adjacentDisplays=*/{SECOND_DISPLAY_ID}); + + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, + {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, SECOND_DISPLAY_ID)}}); + + auto pc = assertPointerControllerCreated(ControllerType::MOUSE); + pc->assertViewportSet(FIRST_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); + + // Move cursor to the secondary display + auto pointerBuilder = PointerBuilder(/*id=*/0, ToolType::MOUSE) + .axis(AMOTION_EVENT_AXIS_RELATIVE_X, /*x=*/100) + .axis(AMOTION_EVENT_AXIS_RELATIVE_Y, /*y=*/0); + mChoreographer.notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(pointerBuilder) + .deviceId(DEVICE_ID) + .displayId(ui::LogicalDisplayId::INVALID) + .build()); + + assertPointerControllerNotCreated(); + pc->assertViewportSet(SECOND_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); +} + +TEST_F(PointerChoreographerDisplayTopologyDefaultMouseDisplayTests, + AddAssociatedDisplayCursorOutsideOfDisplayTopology) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + SCOPED_FLAG_OVERRIDE(connected_displays_associated_display_cursor_bugfix, true); + + // Add three displays, with only first and second display in DisplayTopolgoy + mChoreographer.setDisplayViewports({createViewport(FIRST_DISPLAY_ID), + createViewport(SECOND_DISPLAY_ID), + createViewport(THIRD_DISPLAY_ID)}); + setDisplayTopologyWithDisplays(/*primaryDisplayId=*/FIRST_DISPLAY_ID, + /*adjacentDisplays=*/{SECOND_DISPLAY_ID}); + + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, + {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, + ui::LogicalDisplayId::INVALID)}}); + + auto pc = assertPointerControllerCreated(ControllerType::MOUSE); + pc->assertViewportSet(FIRST_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); + + // Adds a new mouse associated with third display + mChoreographer.notifyInputDevicesChanged( + {/*id=*/1, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, THIRD_DISPLAY_ID)}}); + + pc = assertPointerControllerCreated(ControllerType::MOUSE); + pc->assertViewportSet(THIRD_DISPLAY_ID); + ASSERT_TRUE(pc->isPointerShown()); +} class PointerChoreographerWindowInfoListenerTest : public testing::Test {}; -TEST_F_WITH_FLAGS( - PointerChoreographerWindowInfoListenerTest, - doesNotCrashIfListenerCalledAfterPointerChoreographerDestroyed, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags, - hide_pointer_indicators_for_secure_windows))) { +TEST_F(PointerChoreographerWindowInfoListenerTest, + doesNotCrashIfListenerCalledAfterPointerChoreographerDestroyed) { sp<android::gui::WindowInfosListener> registeredListener; sp<android::gui::WindowInfosListener> localListenerCopy; { diff --git a/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp index 157bee33e1..548df2255b 100644 --- a/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp +++ b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp @@ -89,9 +89,9 @@ namespace vd_flags = android::companion::virtualdevice::flags; */ class RotaryEncoderInputMapperTest : public InputMapperUnitTest { protected: - void SetUp() override { SetUpWithBus(BUS_USB); } - void SetUpWithBus(int bus) override { - InputMapperUnitTest::SetUpWithBus(bus); + void SetUp() override { SetUp(/*bus=*/0, /*isExternal=*/false); } + void SetUp(int bus, bool isExternal) override { + InputMapperUnitTest::SetUp(bus, isExternal); EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL)) .WillRepeatedly(Return(true)); diff --git a/services/inputflinger/tests/ScopedFlagOverride.h b/services/inputflinger/tests/ScopedFlagOverride.h new file mode 100644 index 0000000000..883673c2f5 --- /dev/null +++ b/services/inputflinger/tests/ScopedFlagOverride.h @@ -0,0 +1,58 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <com_android_input_flags.h> +#include <functional> + +namespace android { + +/** + * Provide a local override for a flag value. The value is restored when the object of this class + * goes out of scope. + * This class is not intended to be used directly, because its usage is cumbersome. + * Instead, a wrapper macro SCOPED_FLAG_OVERRIDE is provided. + */ +class ScopedFlagOverride { +public: + ScopedFlagOverride(std::function<bool()> read, std::function<void(bool)> write, bool value) + : mInitialValue(read()), mWriteValue(write) { + mWriteValue(value); + } + ~ScopedFlagOverride() { mWriteValue(mInitialValue); } + +private: + const bool mInitialValue; + std::function<void(bool)> mWriteValue; +}; + +typedef bool (*ReadFlagValueFunction)(); +typedef void (*WriteFlagValueFunction)(bool); + +/** + * Use this macro to locally override a flag value. + * Example usage: + * SCOPED_FLAG_OVERRIDE(enable_multi_device_same_window_stream, false); + * Note: this works by creating a local variable in your current scope. Don't call this twice for + * the same flag, because the variable names will clash! + */ +#define SCOPED_FLAG_OVERRIDE(NAME, VALUE) \ + ReadFlagValueFunction read##NAME = com::android::input::flags::NAME; \ + WriteFlagValueFunction write##NAME = com::android::input::flags::NAME; \ + ScopedFlagOverride override##NAME(read##NAME, write##NAME, (VALUE)) + +} // namespace android diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h index 7fb8895719..1262af7bf9 100644 --- a/services/inputflinger/tests/TestEventMatchers.h +++ b/services/inputflinger/tests/TestEventMatchers.h @@ -32,7 +32,13 @@ namespace android { -namespace { +struct PointF { + float x; + float y; + auto operator<=>(const PointF&) const = default; +}; + +namespace internal { template <typename T> static bool valuesMatch(T value1, T value2) { @@ -43,17 +49,11 @@ static bool valuesMatch(T value1, T value2) { } } -struct PointF { - float x; - float y; - auto operator<=>(const PointF&) const = default; -}; - inline std::string pointFToString(const PointF& p) { return std::string("(") + std::to_string(p.x) + ", " + std::to_string(p.y) + ")"; } -} // namespace +} // namespace internal /// Source class WithSourceMatcher { @@ -453,8 +453,10 @@ public: } if (mPointers != actualPointers) { - *os << "expected pointers " << dumpMap(mPointers, constToString, pointFToString) - << ", but got " << dumpMap(actualPointers, constToString, pointFToString); + *os << "expected pointers " + << dumpMap(mPointers, constToString, internal::pointFToString) + << ", but got " + << dumpMap(actualPointers, constToString, internal::pointFToString); return false; } return true; @@ -469,15 +471,17 @@ public: } if (mPointers != actualPointers) { - *os << "expected pointers " << dumpMap(mPointers, constToString, pointFToString) - << ", but got " << dumpMap(actualPointers, constToString, pointFToString); + *os << "expected pointers " + << dumpMap(mPointers, constToString, internal::pointFToString) + << ", but got " + << dumpMap(actualPointers, constToString, internal::pointFToString); return false; } return true; } void DescribeTo(std::ostream* os) const { - *os << "with pointers " << dumpMap(mPointers, constToString, pointFToString); + *os << "with pointers " << dumpMap(mPointers, constToString, internal::pointFToString); } void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointers"; } @@ -505,8 +509,8 @@ public: } if (mPointerIds != actualPointerIds) { - *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got " - << dumpSet(actualPointerIds); + *os << "expected pointer ids " << dumpContainer(mPointerIds) << ", but got " + << dumpContainer(actualPointerIds); return false; } return true; @@ -519,14 +523,16 @@ public: } if (mPointerIds != actualPointerIds) { - *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got " - << dumpSet(actualPointerIds); + *os << "expected pointer ids " << dumpContainer(mPointerIds) << ", but got " + << dumpContainer(actualPointerIds); return false; } return true; } - void DescribeTo(std::ostream* os) const { *os << "with pointer ids " << dumpSet(mPointerIds); } + void DescribeTo(std::ostream* os) const { + *os << "with pointer ids " << dumpContainer(mPointerIds); + } void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointer ids"; } @@ -719,8 +725,9 @@ public: } const PointerCoords& coords = event.pointerCoords[mPointerIndex]; - bool matches = valuesMatch(mRelX, coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X)) && - valuesMatch(mRelY, coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)); + bool matches = + internal::valuesMatch(mRelX, coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X)) && + internal::valuesMatch(mRelY, coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)); if (!matches) { *os << "expected relative motion (" << mRelX << ", " << mRelY << ") at pointer index " << mPointerIndex << ", but got (" diff --git a/services/inputflinger/tests/TouchpadInputMapper_test.cpp b/services/inputflinger/tests/TouchpadInputMapper_test.cpp index ea69fffeaa..5f5aa63704 100644 --- a/services/inputflinger/tests/TouchpadInputMapper_test.cpp +++ b/services/inputflinger/tests/TouchpadInputMapper_test.cpp @@ -18,10 +18,13 @@ #include <android-base/logging.h> #include <gtest/gtest.h> +#include <input/AccelerationCurve.h> +#include <log/log.h> #include <thread> #include "InputMapperTest.h" #include "InterfaceMocks.h" +#include "TestConstants.h" #include "TestEventMatchers.h" #define TAG "TouchpadInputMapper_test" @@ -121,9 +124,10 @@ protected: */ TEST_F(TouchpadInputMapperTest, HoverAndLeftButtonPress) { mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID); - mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, - /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL); - + DisplayViewport viewport = + createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0, + /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL); + mFakePolicy->addDisplayViewport(viewport); std::list<NotifyArgs> args; args += mMapper->reconfigure(systemTime(SYSTEM_TIME_MONOTONIC), mReaderConfiguration, @@ -190,4 +194,67 @@ TEST_F(TouchpadInputMapperTest, TouchpadHardwareState) { mFakePolicy->assertTouchpadHardwareStateNotified(); } +TEST_F(TouchpadInputMapperTest, TouchpadAccelerationDisabled) { + mReaderConfiguration.touchpadAccelerationEnabled = false; + mReaderConfiguration.touchpadPointerSpeed = 3; + + std::list<NotifyArgs> args = + mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, + InputReaderConfiguration::Change::TOUCHPAD_SETTINGS); + auto* touchpadMapper = static_cast<TouchpadInputMapper*>(mMapper.get()); + + const auto accelCurvePropsDisabled = + touchpadMapper->getGesturePropertyForTesting("Pointer Accel Curve"); + ASSERT_TRUE(accelCurvePropsDisabled.has_value()); + std::vector<double> curveValuesDisabled = accelCurvePropsDisabled.value().getRealValues(); + std::vector<AccelerationCurveSegment> curve = + createFlatAccelerationCurve(mReaderConfiguration.touchpadPointerSpeed); + double expectedBaseGain = curve[0].baseGain; + ASSERT_EQ(curveValuesDisabled[0], std::numeric_limits<double>::infinity()); + ASSERT_EQ(curveValuesDisabled[1], 0); + ASSERT_NEAR(curveValuesDisabled[2], expectedBaseGain, EPSILON); + ASSERT_EQ(curveValuesDisabled[3], 0); +} + +TEST_F(TouchpadInputMapperTest, TouchpadAccelerationEnabled) { + // Enable touchpad acceleration. + mReaderConfiguration.touchpadAccelerationEnabled = true; + mReaderConfiguration.touchpadPointerSpeed = 3; + + std::list<NotifyArgs> args = + mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, + InputReaderConfiguration::Change::TOUCHPAD_SETTINGS); + ASSERT_THAT(args, testing::IsEmpty()); + + auto* touchpadMapper = static_cast<TouchpadInputMapper*>(mMapper.get()); + + // Get the acceleration curve properties when acceleration is enabled. + const auto accelCurvePropsEnabled = + touchpadMapper->getGesturePropertyForTesting("Pointer Accel Curve"); + ASSERT_TRUE(accelCurvePropsEnabled.has_value()); + + // Get the curve values. + std::vector<double> curveValuesEnabled = accelCurvePropsEnabled.value().getRealValues(); + + // Use createAccelerationCurveForPointerSensitivity to get expected curve segments. + std::vector<AccelerationCurveSegment> expectedCurveSegments = + createAccelerationCurveForPointerSensitivity(mReaderConfiguration.touchpadPointerSpeed); + + // Iterate through the segments and compare the values. + for (size_t i = 0; i < expectedCurveSegments.size(); ++i) { + // Check max speed. + if (std::isinf(expectedCurveSegments[i].maxPointerSpeedMmPerS)) { + ASSERT_TRUE(std::isinf(curveValuesEnabled[i * 4 + 0])); + } else { + ASSERT_NEAR(curveValuesEnabled[i * 4 + 0], + expectedCurveSegments[i].maxPointerSpeedMmPerS, EPSILON); + } + + // Check that the x^2 term is zero. + ASSERT_NEAR(curveValuesEnabled[i * 4 + 1], 0, EPSILON); + ASSERT_NEAR(curveValuesEnabled[i * 4 + 2], expectedCurveSegments[i].baseGain, EPSILON); + ASSERT_NEAR(curveValuesEnabled[i * 4 + 3], expectedCurveSegments[i].reciprocal, EPSILON); + } +} + } // namespace android diff --git a/services/inputflinger/tests/fuzzers/Android.bp b/services/inputflinger/tests/fuzzers/Android.bp index 48e19546c5..5000db7d9a 100644 --- a/services/inputflinger/tests/fuzzers/Android.bp +++ b/services/inputflinger/tests/fuzzers/Android.bp @@ -33,8 +33,8 @@ cc_defaults { "frameworks/native/services/inputflinger", ], shared_libs: [ - "libinputreader", "libinputflinger_base", + "libinputreader", ], sanitize: { hwaddress: true, diff --git a/services/inputflinger/tests/fuzzers/FuzzedInputStream.h b/services/inputflinger/tests/fuzzers/FuzzedInputStream.h index 812969bb33..43975f0836 100644 --- a/services/inputflinger/tests/fuzzers/FuzzedInputStream.h +++ b/services/inputflinger/tests/fuzzers/FuzzedInputStream.h @@ -18,10 +18,16 @@ namespace android { -namespace { static constexpr int32_t MAX_RANDOM_POINTERS = 4; static constexpr int32_t MAX_RANDOM_DEVICES = 4; -} // namespace + +// The maximum value that we use for the action button field of NotifyMotionArgs. (We allow multiple +// bits to be set for this since we're just trying to generate a fuzzed event stream that doesn't +// cause crashes when enum values are converted to Rust — we don't necessarily want it to be valid.) +// +// AMOTION_EVENT_BUTTON_STYLUS_SECONDARY should be replaced with whatever AMOTION_EVENT_BUTTON_ +// value is highest if the enum is edited. +static constexpr int8_t MAX_ACTION_BUTTON_VALUE = (AMOTION_EVENT_BUTTON_STYLUS_SECONDARY << 1) - 1; int getFuzzedMotionAction(FuzzedDataProvider& fdp) { int actionMasked = fdp.PickValueInArray<int>({ @@ -187,18 +193,16 @@ NotifyMotionArgs generateFuzzedMotionArgs(IdGenerator& idGenerator, FuzzedDataPr fdp.ConsumeIntegralInRange<nsecs_t>(currentTime - 5E9, currentTime + 5E9); const nsecs_t readTime = downTime; const nsecs_t eventTime = fdp.ConsumeIntegralInRange<nsecs_t>(downTime, downTime + 1E9); + const int32_t actionButton = fdp.ConsumeIntegralInRange<int32_t>(0, MAX_ACTION_BUTTON_VALUE); const float cursorX = fdp.ConsumeIntegralInRange<int>(-10000, 10000); const float cursorY = fdp.ConsumeIntegralInRange<int>(-10000, 10000); return NotifyMotionArgs(idGenerator.nextId(), eventTime, readTime, deviceId, source, displayId, - POLICY_FLAG_PASS_TO_USER, action, - /*actionButton=*/fdp.ConsumeIntegral<int32_t>(), + POLICY_FLAG_PASS_TO_USER, action, actionButton, getFuzzedFlags(fdp, action), AMETA_NONE, getFuzzedButtonState(fdp), MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, - pointerProperties.data(), pointerCoords.data(), - /*xPrecision=*/0, - /*yPrecision=*/0, cursorX, cursorY, downTime, - /*videoFrames=*/{}); + pointerProperties.data(), pointerCoords.data(), /*xPrecision=*/0, + /*yPrecision=*/0, cursorX, cursorY, downTime, /*videoFrames=*/{}); } } // namespace android diff --git a/services/inputflinger/tests/fuzzers/InputDispatcherFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputDispatcherFuzzer.cpp index 79a5ff6e5f..abce931eff 100644 --- a/services/inputflinger/tests/fuzzers/InputDispatcherFuzzer.cpp +++ b/services/inputflinger/tests/fuzzers/InputDispatcherFuzzer.cpp @@ -48,9 +48,9 @@ public: auto [it, _] = mVerifiers.emplace(args.displayId, "Fuzz Verifier"); InputVerifier& verifier = it->second; const Result<void> result = - verifier.processMovement(args.deviceId, args.source, args.action, + verifier.processMovement(args.deviceId, args.source, args.action, args.actionButton, args.getPointerCount(), args.pointerProperties.data(), - args.pointerCoords.data(), args.flags); + args.pointerCoords.data(), args.flags, args.buttonState); if (result.ok()) { return args; } @@ -76,7 +76,6 @@ void scrambleWindow(FuzzedDataProvider& fdp, FakeWindowHandle& window) { window.setDupTouchToWallpaper(fdp.ConsumeBool()); window.setIsWallpaper(fdp.ConsumeBool()); window.setVisible(fdp.ConsumeBool()); - window.setPreventSplitting(fdp.ConsumeBool()); const bool isTrustedOverlay = fdp.ConsumeBool(); window.setTrustedOverlay(isTrustedOverlay); if (isTrustedOverlay) { diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h index a1da39ae14..9a5903981b 100644 --- a/services/inputflinger/tests/fuzzers/MapperHelpers.h +++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h @@ -34,6 +34,28 @@ constexpr size_t kValidTypes[] = {EV_SW, android::EventHubInterface::DEVICE_ADDED, android::EventHubInterface::DEVICE_REMOVED}; +static const android::InputDeviceClass kInputDeviceClasses[] = { + android::InputDeviceClass::KEYBOARD, + android::InputDeviceClass::ALPHAKEY, + android::InputDeviceClass::TOUCH, + android::InputDeviceClass::CURSOR, + android::InputDeviceClass::TOUCH_MT, + android::InputDeviceClass::DPAD, + android::InputDeviceClass::GAMEPAD, + android::InputDeviceClass::SWITCH, + android::InputDeviceClass::JOYSTICK, + android::InputDeviceClass::VIBRATOR, + android::InputDeviceClass::MIC, + android::InputDeviceClass::EXTERNAL_STYLUS, + android::InputDeviceClass::ROTARY_ENCODER, + android::InputDeviceClass::SENSOR, + android::InputDeviceClass::BATTERY, + android::InputDeviceClass::LIGHT, + android::InputDeviceClass::TOUCHPAD, + android::InputDeviceClass::VIRTUAL, + android::InputDeviceClass::EXTERNAL, +}; + constexpr size_t kValidCodes[] = { SYN_REPORT, ABS_MT_SLOT, @@ -105,7 +127,13 @@ public: void addProperty(std::string key, std::string value) { mFuzzConfig.addProperty(key, value); } ftl::Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const override { - return ftl::Flags<InputDeviceClass>(mFdp->ConsumeIntegral<uint32_t>()); + uint32_t flags = 0; + for (auto inputDeviceClass : kInputDeviceClasses) { + if (mFdp->ConsumeBool()) { + flags |= static_cast<uint32_t>(inputDeviceClass); + } + } + return ftl::Flags<InputDeviceClass>(flags); } InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override { return mIdentifier; @@ -332,6 +360,7 @@ public: std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) : mEventHub(eventHub), mPolicy(sp<FuzzInputReaderPolicy>::make(fdp)), mFdp(fdp) {} ~FuzzInputReaderContext() {} + std::string dump() { return "(dump from FuzzInputReaderContext)"; } void updateGlobalMetaState() override {} int32_t getGlobalMetaState() { return mFdp->ConsumeIntegral<int32_t>(); } void disableVirtualKeysUntil(nsecs_t time) override {} @@ -346,7 +375,7 @@ public: } InputReaderPolicyInterface* getPolicy() override { return mPolicy.get(); } EventHubInterface* getEventHub() override { return mEventHub.get(); } - int32_t getNextId() override { return mFdp->ConsumeIntegral<int32_t>(); } + int32_t getNextId() const override { return mFdp->ConsumeIntegral<int32_t>(); } void updateLedMetaState(int32_t metaState) override{}; int32_t getLedMetaState() override { return mFdp->ConsumeIntegral<int32_t>(); }; @@ -367,8 +396,8 @@ private: template <class Fdp> InputDevice getFuzzedInputDevice(Fdp& fdp, FuzzInputReaderContext* context) { InputDeviceIdentifier identifier; - identifier.name = fdp.ConsumeRandomLengthString(16); - identifier.location = fdp.ConsumeRandomLengthString(12); + identifier.name = fdp.ConsumeRandomLengthUtf8String(16); + identifier.location = fdp.ConsumeRandomLengthUtf8String(12); int32_t deviceID = fdp.ConsumeIntegralInRange(0, 5); int32_t deviceGeneration = fdp.ConsumeIntegralInRange(0, 5); return InputDevice(context, deviceID, deviceGeneration, identifier); diff --git a/services/inputflinger/tests/fuzzers/ThreadSafeFuzzedDataProvider.h b/services/inputflinger/tests/fuzzers/ThreadSafeFuzzedDataProvider.h index 2f76f181cb..b2581184e8 100644 --- a/services/inputflinger/tests/fuzzers/ThreadSafeFuzzedDataProvider.h +++ b/services/inputflinger/tests/fuzzers/ThreadSafeFuzzedDataProvider.h @@ -15,7 +15,7 @@ */ #include <fuzzer/FuzzedDataProvider.h> - +#include <algorithm> /** * A thread-safe interface to the FuzzedDataProvider */ @@ -60,6 +60,44 @@ public: return FuzzedDataProvider::ConsumeRandomLengthString(); } + // Converting the string to a UTF-8 string by setting the prefix bits of each + // byte according to UTF-8 encoding rules. + std::string ConsumeRandomLengthUtf8String(size_t max_length) { + std::scoped_lock _l(mLock); + std::string result = FuzzedDataProvider::ConsumeRandomLengthString(max_length); + size_t remaining_bytes = result.length(), idx = 0; + while (remaining_bytes > 0) { + size_t random_byte_size = FuzzedDataProvider::ConsumeIntegralInRange(1, 4); + size_t byte_size = std::min(random_byte_size, remaining_bytes); + switch (byte_size) { + // Prefix byte: 0xxxxxxx + case 1: + result[idx++] &= 0b01111111; + break; + // Prefix bytes: 110xxxxx 10xxxxxx + case 2: + result[idx++] = (result[idx] & 0b00011111) | 0b11000000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + break; + // Prefix bytes: 1110xxxx 10xxxxxx 10xxxxxx + case 3: + result[idx++] = (result[idx] & 0b00001111) | 0b11100000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + break; + // Prefix bytes: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + case 4: + result[idx++] = (result[idx] & 0b00000111) | 0b11110000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + result[idx++] = (result[idx] & 0b00111111) | 0b10000000; + break; + } + remaining_bytes -= byte_size; + } + return result; + } + std::string ConsumeRemainingBytesAsString() { std::scoped_lock _l(mLock); return FuzzedDataProvider::ConsumeRemainingBytesAsString(); diff --git a/services/powermanager/benchmarks/PowerHalAidlBenchmarks.cpp b/services/powermanager/benchmarks/PowerHalAidlBenchmarks.cpp index 61ab47a75a..3a1b426520 100644 --- a/services/powermanager/benchmarks/PowerHalAidlBenchmarks.cpp +++ b/services/powermanager/benchmarks/PowerHalAidlBenchmarks.cpp @@ -40,10 +40,10 @@ using namespace android; using namespace std::chrono_literals; // Values from Boost.aidl and Mode.aidl. -static constexpr int64_t FIRST_BOOST = static_cast<int64_t>(Boost::INTERACTION); -static constexpr int64_t LAST_BOOST = static_cast<int64_t>(Boost::CAMERA_SHOT); -static constexpr int64_t FIRST_MODE = static_cast<int64_t>(Mode::DOUBLE_TAP_TO_WAKE); -static constexpr int64_t LAST_MODE = static_cast<int64_t>(Mode::CAMERA_STREAMING_HIGH); +static constexpr int64_t FIRST_BOOST = static_cast<int64_t>(*ndk::enum_range<Boost>().begin()); +static constexpr int64_t LAST_BOOST = static_cast<int64_t>(*(ndk::enum_range<Boost>().end()-1)); +static constexpr int64_t FIRST_MODE = static_cast<int64_t>(*ndk::enum_range<Mode>().begin()); +static constexpr int64_t LAST_MODE = static_cast<int64_t>(*(ndk::enum_range<Mode>().end()-1)); class DurationWrapper : public WorkDuration { public: @@ -81,14 +81,17 @@ static void runBenchmark(benchmark::State& state, microseconds delay, R (IPower: return; } - while (state.KeepRunning()) { + for (auto _ : state) { ret = (*hal.*fn)(std::forward<Args1>(args1)...); - state.PauseTiming(); - if (!ret.isOk()) state.SkipWithError(ret.getDescription().c_str()); + if (!ret.isOk()) { + state.SkipWithError(ret.getDescription().c_str()); + break; + } if (delay > 0us) { + state.PauseTiming(); testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(delay).count()); + state.ResumeTiming(); } - state.ResumeTiming(); } } @@ -123,14 +126,15 @@ static void runSessionBenchmark(benchmark::State& state, R (IPowerHintSession::* return; } - while (state.KeepRunning()) { + for (auto _ : state) { ret = (*session.*fn)(std::forward<Args1>(args1)...); - state.PauseTiming(); - if (!ret.isOk()) state.SkipWithError(ret.getDescription().c_str()); - if (ONEWAY_API_DELAY > 0us) { - testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(ONEWAY_API_DELAY) - .count()); + if (!ret.isOk()) { + state.SkipWithError(ret.getDescription().c_str()); + break; } + state.PauseTiming(); + testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(ONEWAY_API_DELAY) + .count()); state.ResumeTiming(); } session->close(); @@ -150,11 +154,41 @@ static void BM_PowerHalAidlBenchmarks_isModeSupported(benchmark::State& state) { static void BM_PowerHalAidlBenchmarks_setBoost(benchmark::State& state) { Boost boost = static_cast<Boost>(state.range(0)); + bool isSupported; + std::shared_ptr<IPower> hal = PowerHalLoader::loadAidl(); + + if (hal == nullptr) { + ALOGV("Power HAL not available, skipping test..."); + state.SkipWithMessage("Power HAL unavailable"); + return; + } + + ndk::ScopedAStatus ret = hal->isBoostSupported(boost, &isSupported); + if (!ret.isOk() || !isSupported) { + state.SkipWithMessage("operation unsupported"); + return; + } + runBenchmark(state, ONEWAY_API_DELAY, &IPower::setBoost, boost, 1); } static void BM_PowerHalAidlBenchmarks_setMode(benchmark::State& state) { Mode mode = static_cast<Mode>(state.range(0)); + bool isSupported; + std::shared_ptr<IPower> hal = PowerHalLoader::loadAidl(); + + if (hal == nullptr) { + ALOGV("Power HAL not available, skipping test..."); + state.SkipWithMessage("Power HAL unavailable"); + return; + } + + ndk::ScopedAStatus ret = hal->isModeSupported(mode, &isSupported); + if (!ret.isOk() || !isSupported) { + state.SkipWithMessage("operation unsupported"); + return; + } + runBenchmark(state, ONEWAY_API_DELAY, &IPower::setMode, mode, false); } @@ -178,12 +212,20 @@ static void BM_PowerHalAidlBenchmarks_createHintSession(benchmark::State& state) ALOGV("Power HAL does not support this operation, skipping test..."); state.SkipWithMessage("operation unsupported"); return; + } else if (!ret.isOk()) { + state.SkipWithError(ret.getDescription().c_str()); + return; + } else { + appSession->close(); } - while (state.KeepRunning()) { + for (auto _ : state) { ret = hal->createHintSession(tgid, uid, threadIds, durationNanos, &appSession); + if (!ret.isOk()) { + state.SkipWithError(ret.getDescription().c_str()); + break; + } state.PauseTiming(); - if (!ret.isOk()) state.SkipWithError(ret.getDescription().c_str()); appSession->close(); state.ResumeTiming(); } diff --git a/services/powermanager/benchmarks/PowerHalControllerBenchmarks.cpp b/services/powermanager/benchmarks/PowerHalControllerBenchmarks.cpp index effddda6a4..0fda686231 100644 --- a/services/powermanager/benchmarks/PowerHalControllerBenchmarks.cpp +++ b/services/powermanager/benchmarks/PowerHalControllerBenchmarks.cpp @@ -19,9 +19,9 @@ #include <aidl/android/hardware/power/Boost.h> #include <aidl/android/hardware/power/Mode.h> #include <benchmark/benchmark.h> +#include <chrono> #include <powermanager/PowerHalController.h> #include <testUtil.h> -#include <chrono> using aidl::android::hardware::power::Boost; using aidl::android::hardware::power::Mode; @@ -32,10 +32,10 @@ using namespace android; using namespace std::chrono_literals; // Values from Boost.aidl and Mode.aidl. -static constexpr int64_t FIRST_BOOST = static_cast<int64_t>(Boost::INTERACTION); -static constexpr int64_t LAST_BOOST = static_cast<int64_t>(Boost::CAMERA_SHOT); -static constexpr int64_t FIRST_MODE = static_cast<int64_t>(Mode::DOUBLE_TAP_TO_WAKE); -static constexpr int64_t LAST_MODE = static_cast<int64_t>(Mode::CAMERA_STREAMING_HIGH); +static constexpr int64_t FIRST_BOOST = static_cast<int64_t>(*ndk::enum_range<Boost>().begin()); +static constexpr int64_t LAST_BOOST = static_cast<int64_t>(*(ndk::enum_range<Boost>().end()-1)); +static constexpr int64_t FIRST_MODE = static_cast<int64_t>(*ndk::enum_range<Mode>().begin()); +static constexpr int64_t LAST_MODE = static_cast<int64_t>(*(ndk::enum_range<Mode>().end()-1)); // Delay between oneway method calls to avoid overflowing the binder buffers. static constexpr std::chrono::microseconds ONEWAY_API_DELAY = 100us; @@ -43,11 +43,27 @@ static constexpr std::chrono::microseconds ONEWAY_API_DELAY = 100us; template <typename T, class... Args0, class... Args1> static void runBenchmark(benchmark::State& state, HalResult<T> (PowerHalController::*fn)(Args0...), Args1&&... args1) { - while (state.KeepRunning()) { - PowerHalController controller; + PowerHalController initController; + HalResult<T> result = (initController.*fn)(std::forward<Args1>(args1)...); + if (result.isFailed()) { + state.SkipWithError(result.errorMessage()); + return; + } else if (result.isUnsupported()) { + ALOGV("Power HAL does not support this operation, skipping test..."); + state.SkipWithMessage("operation unsupported"); + return; + } + + for (auto _ : state) { + PowerHalController controller; // new controller to avoid caching HalResult<T> ret = (controller.*fn)(std::forward<Args1>(args1)...); + if (ret.isFailed()) { + state.SkipWithError(ret.errorMessage()); + break; + } state.PauseTiming(); - if (ret.isFailed()) state.SkipWithError("Power HAL request failed"); + testDelaySpin( + std::chrono::duration_cast<std::chrono::duration<float>>(ONEWAY_API_DELAY).count()); state.ResumeTiming(); } } @@ -57,22 +73,27 @@ static void runCachedBenchmark(benchmark::State& state, HalResult<T> (PowerHalController::*fn)(Args0...), Args1&&... args1) { PowerHalController controller; // First call out of test, to cache HAL service and isSupported result. - (controller.*fn)(std::forward<Args1>(args1)...); + HalResult<T> result = (controller.*fn)(std::forward<Args1>(args1)...); + if (result.isFailed()) { + state.SkipWithError(result.errorMessage()); + return; + } else if (result.isUnsupported()) { + ALOGV("Power HAL does not support this operation, skipping test..."); + state.SkipWithMessage("operation unsupported"); + return; + } - while (state.KeepRunning()) { + for (auto _ : state) { HalResult<T> ret = (controller.*fn)(std::forward<Args1>(args1)...); - state.PauseTiming(); if (ret.isFailed()) { - state.SkipWithError("Power HAL request failed"); + state.SkipWithError(ret.errorMessage()); + break; } - testDelaySpin( - std::chrono::duration_cast<std::chrono::duration<float>>(ONEWAY_API_DELAY).count()); - state.ResumeTiming(); } } static void BM_PowerHalControllerBenchmarks_init(benchmark::State& state) { - while (state.KeepRunning()) { + for (auto _ : state) { PowerHalController controller; controller.init(); } @@ -90,12 +111,12 @@ static void BM_PowerHalControllerBenchmarks_initCached(benchmark::State& state) static void BM_PowerHalControllerBenchmarks_setBoost(benchmark::State& state) { Boost boost = static_cast<Boost>(state.range(0)); - runBenchmark(state, &PowerHalController::setBoost, boost, 0); + runBenchmark(state, &PowerHalController::setBoost, boost, 1); } static void BM_PowerHalControllerBenchmarks_setBoostCached(benchmark::State& state) { Boost boost = static_cast<Boost>(state.range(0)); - runCachedBenchmark(state, &PowerHalController::setBoost, boost, 0); + runCachedBenchmark(state, &PowerHalController::setBoost, boost, 1); } static void BM_PowerHalControllerBenchmarks_setMode(benchmark::State& state) { diff --git a/services/powermanager/benchmarks/PowerHalHidlBenchmarks.cpp b/services/powermanager/benchmarks/PowerHalHidlBenchmarks.cpp index bcb376b799..95fd0c2a4d 100644 --- a/services/powermanager/benchmarks/PowerHalHidlBenchmarks.cpp +++ b/services/powermanager/benchmarks/PowerHalHidlBenchmarks.cpp @@ -54,14 +54,17 @@ static void runBenchmark(benchmark::State& state, microseconds delay, Return<R> return; } - while (state.KeepRunning()) { + for (auto _ : state) { Return<R> ret = (*hal.*fn)(std::forward<Args1>(args1)...); - state.PauseTiming(); - if (!ret.isOk()) state.SkipWithError(ret.description().c_str()); + if (!ret.isOk()) { + state.SkipWithError(ret.description().c_str()); + break; + } if (delay > 0us) { + state.PauseTiming(); testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(delay).count()); + state.ResumeTiming(); } - state.ResumeTiming(); } } diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp index 8c80dd8ac8..9ecd101326 100644 --- a/services/sensorservice/Android.bp +++ b/services/sensorservice/Android.bp @@ -11,7 +11,7 @@ aconfig_declarations { name: "sensorservice_flags", package: "com.android.frameworks.sensorservice.flags", container: "system", - srcs: ["senserservice_flags.aconfig"], + srcs: ["sensorservice_flags.aconfig"], } cc_aconfig_library { @@ -61,38 +61,38 @@ cc_library { ], shared_libs: [ + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", + "android.hardware.sensors@1.0", + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "libaconfig_storage_read_api_cc", + "libactivitymanager_aidl", + "libbase", + "libbatterystats_aidl", + "libbinder", + "libbinder_ndk", + "libcrypto", "libcutils", + "libfmq", "libhardware", "libhardware_legacy", - "libutils", + "libhidlbase", "liblog", - "libactivitymanager_aidl", - "libbatterystats_aidl", - "libbinder", - "libsensor", - "libsensorprivacy", "libpermission", "libprotoutil", - "libcrypto", - "libbase", - "libhidlbase", - "libfmq", - "libbinder_ndk", + "libsensor", + "libsensorprivacy", + "libutils", "packagemanager_aidl-cpp", - "android.hardware.sensors@1.0", - "android.hardware.sensors@2.0", - "android.hardware.sensors@2.1", - "android.hardware.common-V2-ndk", - "android.hardware.common.fmq-V1-ndk", "server_configurable_flags", - "libaconfig_storage_read_api_cc", ], static_libs: [ - "libaidlcommonsupport", - "android.hardware.sensors@1.0-convert", "android.hardware.sensors-V1-convert", "android.hardware.sensors-V3-ndk", + "android.hardware.sensors@1.0-convert", + "libaidlcommonsupport", "sensorservice_flags_c_lib", ], @@ -100,9 +100,9 @@ cc_library { export_shared_lib_headers: [ "libactivitymanager_aidl", + "libpermission", "libsensor", "libsensorprivacy", - "libpermission", ], afdo: true, @@ -120,9 +120,9 @@ cc_binary { srcs: ["main_sensorservice.cpp"], shared_libs: [ - "libsensorservice", - "libsensorprivacy", "libbinder", + "libsensorprivacy", + "libsensorservice", "libutils", ], diff --git a/services/sensorservice/OWNERS b/services/sensorservice/OWNERS index 7347ac74e6..3ccdc17061 100644 --- a/services/sensorservice/OWNERS +++ b/services/sensorservice/OWNERS @@ -1 +1,3 @@ bduddie@google.com +arthuri@google.com +rockyfang@google.com diff --git a/services/sensorservice/aidl/fuzzer/Android.bp b/services/sensorservice/aidl/fuzzer/Android.bp index 880df08866..f38cf5ac17 100644 --- a/services/sensorservice/aidl/fuzzer/Android.bp +++ b/services/sensorservice/aidl/fuzzer/Android.bp @@ -22,6 +22,7 @@ cc_fuzz { "android.hardware.sensors-V1-convert", "android.hardware.sensors-V3-ndk", "android.hardware.common-V2-ndk", + "framework-permission-aidl-cpp", "libsensor", "libfakeservicemanager", "libcutils", diff --git a/services/sensorservice/senserservice_flags.aconfig b/services/sensorservice/sensorservice_flags.aconfig index 7abfbaab07..63089737e3 100644 --- a/services/sensorservice/senserservice_flags.aconfig +++ b/services/sensorservice/sensorservice_flags.aconfig @@ -28,3 +28,23 @@ flag { description: "When this flag is enabled, sensor service will only erase dynamic sensor data at the end of the threadLoop to prevent race condition." bug: "329020894" } + +flag { + name: "enforce_permissions_for_all_target_sdk" + namespace: "sensors" + description: "When this flag is enabled, sensor service will enforce permissions for all target sdks." + bug: "389176817" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "disable_vndk_forged_name" + namespace: "sensors" + description: "When this flag is enabled, sensor manager will not use forged name to determine if an access is from VNDK" + bug: "398253250" + metadata { + purpose: PURPOSE_BUGFIX + } +}
\ No newline at end of file diff --git a/services/stats/Android.bp b/services/stats/Android.bp index f698515545..d588017737 100644 --- a/services/stats/Android.bp +++ b/services/stats/Android.bp @@ -29,10 +29,15 @@ cc_library_shared { "libexpresslog", "libhidlbase", "liblog", - "libstatslog", "libstatssocket", "libutils", ], + generated_sources: [ + "statslog_hidl.cpp", + ], + generated_headers: [ + "statslog_hidl.h", + ], export_include_dirs: [ "include/", ], @@ -47,3 +52,28 @@ cc_library_shared { "android.frameworks.stats-service.xml", ], } + +genrule { + name: "statslog_hidl.h", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen)" + + " --header $(genDir)/statslog_hidl.h" + + " --module statshidl" + + " --namespace android,util,statshidl", + out: [ + "statslog_hidl.h", + ], +} + +genrule { + name: "statslog_hidl.cpp", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen)" + + " --cpp $(genDir)/statslog_hidl.cpp" + + " --module statshidl" + + " --namespace android,util,statshidl" + + " --importHeader statslog_hidl.h", + out: [ + "statslog_hidl.cpp", + ], +} diff --git a/services/stats/OWNERS b/services/stats/OWNERS index a61babf32e..791b711de8 100644 --- a/services/stats/OWNERS +++ b/services/stats/OWNERS @@ -1,9 +1,7 @@ jeffreyhuang@google.com joeo@google.com -jtnguyen@google.com muhammadq@google.com ruchirr@google.com singhtejinder@google.com tsaichristine@google.com yaochen@google.com -yro@google.com diff --git a/services/stats/StatsAidl.cpp b/services/stats/StatsAidl.cpp index b22f903654..66f7682dd8 100644 --- a/services/stats/StatsAidl.cpp +++ b/services/stats/StatsAidl.cpp @@ -26,9 +26,8 @@ #include <log/log.h> #include <stats_annotations.h> #include <stats_event.h> -#include <statslog.h> -#include <unordered_map> +#include <map> namespace { static const char* g_AtomErrorMetricName = @@ -118,8 +117,8 @@ ndk::ScopedAStatus StatsHal::reportVendorAtom(const VendorAtom& vendorAtom) { } } - // populate map for quickier access for VendorAtomValue associated annotations by value index - std::unordered_map<int, int> fieldIndexToAnnotationSetMap; + // populate map for quicker access for VendorAtomValue associated annotations by value index + std::map<int, int> fieldIndexToAnnotationSetMap; if (vendorAtom.valuesAnnotations) { const std::vector<std::optional<AnnotationSet>>& valuesAnnotations = *vendorAtom.valuesAnnotations; diff --git a/services/stats/StatsHal.cpp b/services/stats/StatsHal.cpp index 19176d9aaf..0ffa4c3947 100644 --- a/services/stats/StatsHal.cpp +++ b/services/stats/StatsHal.cpp @@ -20,7 +20,7 @@ #include "StatsHal.h" #include <log/log.h> -#include <statslog.h> +#include <statslog_hidl.h> namespace android { namespace frameworks { @@ -32,24 +32,27 @@ StatsHal::StatsHal() { } hardware::Return<void> StatsHal::reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) { - android::util::stats_write(android::util::SPEAKER_IMPEDANCE_REPORTED, - speakerImpedance.speakerLocation, speakerImpedance.milliOhms); + android::util::statshidl::stats_write(android::util::statshidl::SPEAKER_IMPEDANCE_REPORTED, + speakerImpedance.speakerLocation, + speakerImpedance.milliOhms); return hardware::Void(); } hardware::Return<void> StatsHal::reportHardwareFailed(const HardwareFailed& hardwareFailed) { - android::util::stats_write(android::util::HARDWARE_FAILED, int32_t(hardwareFailed.hardwareType), - hardwareFailed.hardwareLocation, int32_t(hardwareFailed.errorCode)); + android::util::statshidl::stats_write( + android::util::statshidl::HARDWARE_FAILED, int32_t(hardwareFailed.hardwareType), + hardwareFailed.hardwareLocation, int32_t(hardwareFailed.errorCode)); return hardware::Void(); } hardware::Return<void> StatsHal::reportPhysicalDropDetected( const PhysicalDropDetected& physicalDropDetected) { - android::util::stats_write( - android::util::PHYSICAL_DROP_DETECTED, int32_t(physicalDropDetected.confidencePctg), - physicalDropDetected.accelPeak, physicalDropDetected.freefallDuration); + android::util::statshidl::stats_write(android::util::statshidl::PHYSICAL_DROP_DETECTED, + int32_t(physicalDropDetected.confidencePctg), + physicalDropDetected.accelPeak, + physicalDropDetected.freefallDuration); return hardware::Void(); } @@ -60,19 +63,19 @@ hardware::Return<void> StatsHal::reportChargeCycles(const ChargeCycles& chargeCy for (int i = 0; i < 10 - initialSize; i++) { buckets.push_back(0); // Push 0 for buckets that do not exist. } - android::util::stats_write(android::util::CHARGE_CYCLES_REPORTED, buckets[0], buckets[1], - buckets[2], buckets[3], buckets[4], buckets[5], buckets[6], - buckets[7], buckets[8], buckets[9]); + android::util::statshidl::stats_write( + android::util::statshidl::CHARGE_CYCLES_REPORTED, buckets[0], buckets[1], buckets[2], + buckets[3], buckets[4], buckets[5], buckets[6], buckets[7], buckets[8], buckets[9]); return hardware::Void(); } hardware::Return<void> StatsHal::reportBatteryHealthSnapshot( const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) { - android::util::stats_write( - android::util::BATTERY_HEALTH_SNAPSHOT, int32_t(batteryHealthSnapshotArgs.type), - batteryHealthSnapshotArgs.temperatureDeciC, batteryHealthSnapshotArgs.voltageMicroV, - batteryHealthSnapshotArgs.currentMicroA, + android::util::statshidl::stats_write( + android::util::statshidl::BATTERY_HEALTH_SNAPSHOT, + int32_t(batteryHealthSnapshotArgs.type), batteryHealthSnapshotArgs.temperatureDeciC, + batteryHealthSnapshotArgs.voltageMicroV, batteryHealthSnapshotArgs.currentMicroA, batteryHealthSnapshotArgs.openCircuitVoltageMicroV, batteryHealthSnapshotArgs.resistanceMicroOhm, batteryHealthSnapshotArgs.levelPercent); @@ -80,23 +83,24 @@ hardware::Return<void> StatsHal::reportBatteryHealthSnapshot( } hardware::Return<void> StatsHal::reportSlowIo(const SlowIo& slowIo) { - android::util::stats_write(android::util::SLOW_IO, int32_t(slowIo.operation), slowIo.count); + android::util::statshidl::stats_write(android::util::statshidl::SLOW_IO, + int32_t(slowIo.operation), slowIo.count); return hardware::Void(); } hardware::Return<void> StatsHal::reportBatteryCausedShutdown( const BatteryCausedShutdown& batteryCausedShutdown) { - android::util::stats_write(android::util::BATTERY_CAUSED_SHUTDOWN, - batteryCausedShutdown.voltageMicroV); + android::util::statshidl::stats_write(android::util::statshidl::BATTERY_CAUSED_SHUTDOWN, + batteryCausedShutdown.voltageMicroV); return hardware::Void(); } hardware::Return<void> StatsHal::reportUsbPortOverheatEvent( const UsbPortOverheatEvent& usbPortOverheatEvent) { - android::util::stats_write( - android::util::USB_PORT_OVERHEAT_EVENT_REPORTED, + android::util::statshidl::stats_write( + android::util::statshidl::USB_PORT_OVERHEAT_EVENT_REPORTED, usbPortOverheatEvent.plugTemperatureDeciC, usbPortOverheatEvent.maxTemperatureDeciC, usbPortOverheatEvent.timeToOverheat, usbPortOverheatEvent.timeToHysteresis, usbPortOverheatEvent.timeToInactive); @@ -105,9 +109,10 @@ hardware::Return<void> StatsHal::reportUsbPortOverheatEvent( } hardware::Return<void> StatsHal::reportSpeechDspStat(const SpeechDspStat& speechDspStat) { - android::util::stats_write(android::util::SPEECH_DSP_STAT_REPORTED, - speechDspStat.totalUptimeMillis, speechDspStat.totalDowntimeMillis, - speechDspStat.totalCrashCount, speechDspStat.totalRecoverCount); + android::util::statshidl::stats_write( + android::util::statshidl::SPEECH_DSP_STAT_REPORTED, speechDspStat.totalUptimeMillis, + speechDspStat.totalDowntimeMillis, speechDspStat.totalCrashCount, + speechDspStat.totalRecoverCount); return hardware::Void(); } diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 05f7d1ba21..9aa1ffa96f 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -26,15 +26,15 @@ cc_aconfig_library { cc_defaults { name: "surfaceflinger_defaults", cflags: [ + "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION", "-Wall", + "-Wconversion", "-Werror", "-Wextra", "-Wformat", "-Wthread-safety", - "-Wunused", "-Wunreachable-code", - "-Wconversion", - "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION", + "-Wunused", ], } @@ -43,39 +43,41 @@ cc_defaults { defaults: [ "android.hardware.graphics.composer3-ndk_shared", "librenderengine_deps", - "libtimestats_deps", "libsurfaceflinger_common_deps", - "surfaceflinger_defaults", "libsurfaceflinger_proto_deps", + "libtimestats_deps", "poweradvisor_deps", + "surfaceflinger_defaults", ], cflags: [ - "-DLOG_TAG=\"SurfaceFlinger\"", - "-DGL_GLEXT_PROTOTYPES", "-DEGL_EGLEXT_PROTOTYPES", + "-DGL_GLEXT_PROTOTYPES", + "-DLOG_TAG=\"SurfaceFlinger\"", ], shared_libs: [ + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", "android.hardware.configstore-utils", "android.hardware.configstore@1.0", "android.hardware.configstore@1.1", "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.common@1.2", - "android.hardware.common-V2-ndk", - "android.hardware.common.fmq-V1-ndk", "android.hardware.graphics.composer@2.1", "android.hardware.graphics.composer@2.2", "android.hardware.graphics.composer@2.3", "android.hardware.graphics.composer@2.4", "android.os.flags-aconfig-cc-host", + "libEGL", + "libGLESv1_CM", + "libGLESv2", + "libSurfaceFlingerProp", + "libaconfig_storage_read_api_cc", "libbase", "libbinder", "libbinder_ndk", "libcutils", - "libEGL", "libfmq", - "libGLESv1_CM", - "libGLESv2", "libgui", "libhidlbase", "liblog", @@ -86,14 +88,11 @@ cc_defaults { "libsync", "libui", "libutils", - "libSurfaceFlingerProp", - "libaconfig_storage_read_api_cc", ], static_libs: [ "iinputflinger_aidl_lib_static", "libaidlcommonsupport", "libcompositionengine", - "libframetimeline", "libgui_aidl_static", "libperfetto_client_experimental", "librenderengine", @@ -105,11 +104,11 @@ cc_defaults { "libtonemap", ], header_libs: [ + "android.hardware.graphics.composer3-command-buffer", "android.hardware.graphics.composer@2.1-command-buffer", "android.hardware.graphics.composer@2.2-command-buffer", "android.hardware.graphics.composer@2.3-command-buffer", "android.hardware.graphics.composer@2.4-command-buffer", - "android.hardware.graphics.composer3-command-buffer", ], export_static_lib_headers: [ "libcompositionengine", @@ -125,8 +124,8 @@ cc_defaults { "android.hardware.graphics.composer@2.2", "android.hardware.graphics.composer@2.3", "android.hardware.graphics.composer@2.4", - "libpowermanager", "libhidlbase", + "libpowermanager", ], // TODO (marissaw): this library is not used by surfaceflinger. This is here so // the library compiled in a way that is accessible to system partition when running @@ -177,7 +176,6 @@ cc_library_headers { filegroup { name: "libsurfaceflinger_backend_sources", srcs: [ - "PowerAdvisor/*.cpp", "DisplayHardware/AidlComposerHal.cpp", "DisplayHardware/ComposerHal.cpp", "DisplayHardware/FramebufferSurface.cpp", @@ -185,6 +183,7 @@ filegroup { "DisplayHardware/HWComposer.cpp", "DisplayHardware/HidlComposerHal.cpp", "DisplayHardware/VirtualDisplaySurface.cpp", + "PowerAdvisor/*.cpp", ], } @@ -206,38 +205,35 @@ filegroup { "Display/DisplayModeController.cpp", "Display/DisplaySnapshot.cpp", "DisplayDevice.cpp", - "DisplayRenderArea.cpp", "Effects/Daltonizer.cpp", + "FpsReporter.cpp", + "FrameTimeline/FrameTimeline.cpp", + "FrameTracer/FrameTracer.cpp", + "FrameTracker.cpp", "FrontEnd/LayerCreationArgs.cpp", "FrontEnd/LayerHandle.cpp", - "FrontEnd/LayerSnapshot.cpp", - "FrontEnd/LayerSnapshotBuilder.cpp", "FrontEnd/LayerHierarchy.cpp", "FrontEnd/LayerLifecycleManager.cpp", + "FrontEnd/LayerSnapshot.cpp", + "FrontEnd/LayerSnapshotBuilder.cpp", "FrontEnd/RequestedLayerState.cpp", "FrontEnd/TransactionHandler.cpp", - "FpsReporter.cpp", - "FrameTracer/FrameTracer.cpp", - "FrameTracker.cpp", "HdrLayerInfoReporter.cpp", "HdrSdrRatioOverlay.cpp", "Jank/JankTracker.cpp", - "WindowInfosListenerInvoker.cpp", "Layer.cpp", "LayerFE.cpp", "LayerProtoHelper.cpp", - "LayerRenderArea.cpp", "LayerVector.cpp", "NativeWindowSurface.cpp", "RefreshRateOverlay.cpp", "RegionSamplingThread.cpp", - "RenderArea.cpp", "Scheduler/EventThread.cpp", "Scheduler/FrameRateOverrideMappings.cpp", - "Scheduler/OneShotTimer.cpp", "Scheduler/LayerHistory.cpp", "Scheduler/LayerInfo.cpp", "Scheduler/MessageQueue.cpp", + "Scheduler/OneShotTimer.cpp", "Scheduler/RefreshRateSelector.cpp", "Scheduler/Scheduler.cpp", "Scheduler/SmallAreaDetectionAllowMappings.cpp", @@ -253,19 +249,20 @@ filegroup { "Tracing/LayerDataSource.cpp", "Tracing/LayerTracing.cpp", "Tracing/TransactionDataSource.cpp", - "Tracing/TransactionTracing.cpp", "Tracing/TransactionProtoParser.cpp", + "Tracing/TransactionTracing.cpp", "Tracing/tools/LayerTraceGenerator.cpp", "TransactionCallbackInvoker.cpp", "TunnelModeEnabledReporter.cpp", + "WindowInfosListenerInvoker.cpp", ], } cc_defaults { name: "libsurfaceflinger_binary", defaults: [ - "surfaceflinger_defaults", "libsurfaceflinger_production_defaults", + "surfaceflinger_defaults", ], cflags: [ "-DLOG_TAG=\"SurfaceFlinger\"", @@ -331,9 +328,9 @@ cc_library_shared { "android.hardware.configstore@1.1", "android.hardware.graphics.common@1.2", "libhidlbase", + "liblog", "libui", "libutils", - "liblog", ], static_libs: [ "libSurfaceFlingerProperties", @@ -354,10 +351,10 @@ cc_library { generated_headers: ["statslog_surfaceflinger.h"], export_generated_headers: ["statslog_surfaceflinger.h"], shared_libs: [ + "android.os.statsbootstrap_aidl-cpp", "libbinder", "libstatsbootstrap", "libutils", - "android.os.statsbootstrap_aidl-cpp", ], } diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index abeb2a92eb..6088e255df 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -53,7 +53,6 @@ binder::Status Client::createSurface(const std::string& name, int32_t flags, const sp<IBinder>& parent, const gui::LayerMetadata& metadata, gui::CreateSurfaceResult* outResult) { // We rely on createLayer to check permissions. - sp<IBinder> handle; LayerCreationArgs args(mFlinger.get(), sp<Client>::fromExisting(this), name.c_str(), static_cast<uint32_t>(flags), std::move(metadata)); args.parentHandle = parent; @@ -101,7 +100,6 @@ binder::Status Client::getLayerFrameStats(const sp<IBinder>& handle, gui::FrameS binder::Status Client::mirrorSurface(const sp<IBinder>& mirrorFromHandle, gui::CreateSurfaceResult* outResult) { - sp<IBinder> handle; LayerCreationArgs args(mFlinger.get(), sp<Client>::fromExisting(this), "MirrorRoot", 0 /* flags */, gui::LayerMetadata()); status_t status = mFlinger->mirrorLayer(args, mirrorFromHandle, *outResult); @@ -109,12 +107,11 @@ binder::Status Client::mirrorSurface(const sp<IBinder>& mirrorFromHandle, } binder::Status Client::mirrorDisplay(int64_t displayId, gui::CreateSurfaceResult* outResult) { - sp<IBinder> handle; LayerCreationArgs args(mFlinger.get(), sp<Client>::fromExisting(this), "MirrorRoot-" + std::to_string(displayId), 0 /* flags */, gui::LayerMetadata()); - std::optional<DisplayId> id = DisplayId::fromValue(static_cast<uint64_t>(displayId)); - status_t status = mFlinger->mirrorDisplay(*id, args, *outResult); + const DisplayId id = DisplayId::fromValue(static_cast<uint64_t>(displayId)); + status_t status = mFlinger->mirrorDisplay(id, args, *outResult); return binderStatusFromStatusT(status); } diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h index e32cc02974..fd58191ed2 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h @@ -53,7 +53,7 @@ public: createLayerFECompositionState() = 0; virtual HWComposer& getHwComposer() const = 0; - virtual void setHwComposer(std::unique_ptr<HWComposer>) = 0; + virtual void setHwComposer(HWComposer*) = 0; virtual renderengine::RenderEngine& getRenderEngine() const = 0; virtual void setRenderEngine(renderengine::RenderEngine*) = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h index 252adaa8e3..2c0a66fac3 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h @@ -34,7 +34,7 @@ class CompositionEngine; * A parameter object for creating Display instances */ struct DisplayCreationArgs { - DisplayId id; + DisplayIdVariant idVariant; // Size of the display in pixels ui::Size pixels = ui::kInvalidSize; @@ -68,8 +68,8 @@ class DisplayCreationArgsBuilder { public: DisplayCreationArgs build() { return std::move(mArgs); } - DisplayCreationArgsBuilder& setId(DisplayId id) { - mArgs.id = id; + DisplayCreationArgsBuilder& setId(DisplayIdVariant idVariant) { + mArgs.idVariant = idVariant; return *this; } diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h index cda4edc216..780758e2a3 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h @@ -19,6 +19,7 @@ #include <optional> #include <ostream> #include <unordered_set> +#include "aidl/android/hardware/graphics/composer3/Composition.h" #include "ui/LayerStack.h" // TODO(b/129481165): remove the #pragma below and fix conversion issues @@ -121,6 +122,8 @@ public: // True if layers with 170M dataspace should be overridden to sRGB. const bool treat170mAsSrgb; + + std::shared_ptr<gui::DisplayLuts> luts; }; // A superset of LayerSettings required by RenderEngine to compose a layer @@ -131,6 +134,9 @@ public: // Currently latched frame number, 0 if invalid. uint64_t frameNumber = 0; + + // layer serial number, -1 if invalid. + int32_t sequence = -1; }; // Describes the states of the release fence. Checking the states allows checks @@ -173,6 +179,28 @@ public: // Whether the layer should be rendered with rounded corners. virtual bool hasRoundedCorners() const = 0; virtual void setWasClientComposed(const sp<Fence>&) {} + + // These fields are all copied from the last written HWC state. + // This state is only used for debugging purposes. + struct HwcLayerDebugState { + aidl::android::hardware::graphics::composer3::Composition lastCompositionType = + aidl::android::hardware::graphics::composer3::Composition::INVALID; + // Corresponds to passing an alpha of 0 to HWC2::Layer::setPlaneAlpha. + bool wasSkipped = false; + + // Indicates whether the compositionengine::OutputLayer had properties overwritten. + // Not directly passed to HWC. + bool wasOverridden = false; + + // Corresponds to the GraphicBuffer ID of the buffer passed to HWC2::Layer::setBuffer. + // This buffer corresponds to a CachedSet that the LayerFE was flattened to. + uint64_t overrideBufferId = 0; + }; + + // Used for debugging purposes, e.g. perfetto tracing, dumpsys. + virtual void setLastHwcState(const LayerFE::HwcLayerDebugState &hwcState) = 0; + virtual const HwcLayerDebugState &getLastHwcState() const = 0; + virtual const gui::LayerMetadata* getMetadata() const = 0; virtual const gui::LayerMetadata* getRelativeMetadata() const = 0; }; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h index bda7856596..4266da4b07 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h @@ -170,6 +170,7 @@ public: // Returns the DisplayId the output represents, if it has one virtual ftl::Optional<DisplayId> getDisplayId() const = 0; + virtual ftl::Optional<DisplayIdVariant> getDisplayIdVariant() const = 0; // Enables (or disables) composition on this output virtual void setCompositionEnabled(bool) = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h index c1b864df02..c0243b81db 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h @@ -145,7 +145,7 @@ public: // Applies a HWC device layer lut virtual void applyDeviceLayerLut( - ndk::ScopedFileDescriptor, + ::android::base::unique_fd, std::vector<std::pair< int, aidl::android::hardware::graphics::composer3::LutProperties>>) = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h index 45208dd3c7..2992b6d843 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h @@ -31,7 +31,7 @@ public: override; HWComposer& getHwComposer() const override; - void setHwComposer(std::unique_ptr<HWComposer>) override; + void setHwComposer(HWComposer*) override; renderengine::RenderEngine& getRenderEngine() const override; void setRenderEngine(renderengine::RenderEngine*) override; @@ -59,7 +59,7 @@ public: void setNeedsAnotherUpdateForTest(bool); private: - std::unique_ptr<HWComposer> mHwComposer; + HWComposer* mHwComposer; renderengine::RenderEngine* mRenderEngine; std::shared_ptr<TimeStats> mTimeStats; bool mNeedsAnotherUpdate = false; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h index 5519aafe11..ec87acc372 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h @@ -46,6 +46,7 @@ public: // compositionengine::Output overrides ftl::Optional<DisplayId> getDisplayId() const override; + ftl::Optional<DisplayIdVariant> getDisplayIdVariant() const override; bool isValid() const override; void dump(std::string&) const override; using compositionengine::impl::Output::setReleasedLayers; @@ -104,8 +105,11 @@ private: override; bool hasPictureProcessing() const override; int32_t getMaxLayerPictureProfiles() const override; + bool isGpuVirtualDisplay() const { + return std::holds_alternative<GpuVirtualDisplayId>(mIdVariant); + } - DisplayId mId; + DisplayIdVariant mIdVariant; bool mIsDisconnected = false; adpf::PowerAdvisor* mPowerAdvisor = nullptr; bool mHasPictureProcessing = false; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h index 0ccdd22919..873764b065 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h @@ -45,6 +45,7 @@ public: // compositionengine::Output overrides bool isValid() const override; ftl::Optional<DisplayId> getDisplayId() const override; + ftl::Optional<DisplayIdVariant> getDisplayIdVariant() const override; void setCompositionEnabled(bool) override; void setLayerCachingEnabled(bool) override; void setLayerCachingTexturePoolEnabled(bool) override; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h index 0063eee0e1..efddc857cd 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h @@ -68,7 +68,7 @@ public: aidl::android::hardware::graphics::composer3::Composition) override; void prepareForDeviceLayerRequests() override; void applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest request) override; - void applyDeviceLayerLut(ndk::ScopedFileDescriptor, + void applyDeviceLayerLut(::android::base::unique_fd, std::vector<std::pair<int, LutProperties>>) override; bool needsFiltering() const override; std::optional<LayerFE::LayerSettings> getOverrideCompositionSettings() const override; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h index f934cb20a0..e42b9b12f4 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h @@ -253,7 +253,6 @@ private: std::unordered_map<size_t, size_t> mFinalLayerCounts; size_t mCachedSetCreationCount = 0; size_t mCachedSetCreationCost = 0; - std::unordered_map<size_t, size_t> mInvalidatedCachedSetAges; }; } // namespace compositionengine::impl::planner diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h index a1b728232c..bb1a2227be 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h @@ -37,7 +37,7 @@ public: std::unique_ptr<compositionengine::LayerFECompositionState>()); MOCK_CONST_METHOD0(getHwComposer, HWComposer&()); - MOCK_METHOD1(setHwComposer, void(std::unique_ptr<HWComposer>)); + MOCK_METHOD1(setHwComposer, void(HWComposer*)); MOCK_CONST_METHOD0(getRenderEngine, renderengine::RenderEngine&()); MOCK_METHOD1(setRenderEngine, void(renderengine::RenderEngine*)); diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h index 272fa3eef7..d2a5a2066c 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h @@ -59,6 +59,10 @@ public: MOCK_CONST_METHOD0(getMetadata, gui::LayerMetadata*()); MOCK_CONST_METHOD0(getRelativeMetadata, gui::LayerMetadata*()); MOCK_METHOD0(onPictureProfileCommitted, void()); + MOCK_METHOD(void, setLastHwcState, + (const HwcLayerDebugState&), (override)); + MOCK_METHOD(const HwcLayerDebugState&, getLastHwcState, + (), (const, override)); }; } // namespace android::compositionengine::mock diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h index f2c265ad2e..eaa3dd37ec 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h @@ -35,6 +35,7 @@ public: MOCK_CONST_METHOD0(isValid, bool()); MOCK_CONST_METHOD0(getDisplayId, ftl::Optional<DisplayId>()); + MOCK_CONST_METHOD0(getDisplayIdVariant, ftl::Optional<DisplayIdVariant>()); MOCK_METHOD1(setCompositionEnabled, void(bool)); MOCK_METHOD1(setLayerCachingEnabled, void(bool)); diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h index 09c47f0224..be36db6fd1 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h @@ -60,7 +60,7 @@ public: MOCK_CONST_METHOD0(needsFiltering, bool()); MOCK_CONST_METHOD0(getOverrideCompositionSettings, std::optional<LayerFE::LayerSettings>()); MOCK_METHOD(void, applyDeviceLayerLut, - (ndk::ScopedFileDescriptor, + (::android::base::unique_fd, (std::vector<std::pair< int, aidl::android::hardware::graphics::composer3::LutProperties>>))); MOCK_METHOD(int64_t, getPictureProfilePriority, (), (const)); diff --git a/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp b/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp index d9018bc3ab..dc841952c9 100644 --- a/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp +++ b/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp @@ -38,7 +38,8 @@ inline bool equalIgnoringSource(const renderengine::LayerSettings& lhs, lhs.disableBlending == rhs.disableBlending && lhs.shadow == rhs.shadow && lhs.backgroundBlurRadius == rhs.backgroundBlurRadius && lhs.stretchEffect == rhs.stretchEffect && - lhs.edgeExtensionEffect == rhs.edgeExtensionEffect; + lhs.edgeExtensionEffect == rhs.edgeExtensionEffect && + lhs.whitePointNits == rhs.whitePointNits; } inline bool equalIgnoringBuffer(const renderengine::Buffer& lhs, const renderengine::Buffer& rhs) { diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp index cfcce473a2..ab2a03cd60 100644 --- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp +++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp @@ -58,11 +58,11 @@ CompositionEngine::createLayerFECompositionState() { } HWComposer& CompositionEngine::getHwComposer() const { - return *mHwComposer.get(); + return *mHwComposer; } -void CompositionEngine::setHwComposer(std::unique_ptr<HWComposer> hwComposer) { - mHwComposer = std::move(hwComposer); +void CompositionEngine::setHwComposer(HWComposer* hwComposer) { + mHwComposer = hwComposer; } renderengine::RenderEngine& CompositionEngine::getRenderEngine() const { @@ -91,13 +91,13 @@ nsecs_t CompositionEngine::getLastFrameRefreshTimestamp() const { namespace { void offloadOutputs(Outputs& outputs) { - if (!FlagManager::getInstance().multithreaded_present() || outputs.size() < 2) { + if (outputs.size() < 2) { return; } ui::PhysicalDisplayVector<compositionengine::Output*> outputsToOffload; for (const auto& output : outputs) { - if (!ftl::Optional(output->getDisplayId()).and_then(HalDisplayId::tryCast)) { + if (!output->getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) { // Not HWC-enabled, so it is always client-composited. No need to offload. continue; } diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp index e37ce0a0eb..5a546777f4 100644 --- a/services/surfaceflinger/CompositionEngine/src/Display.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp @@ -52,7 +52,7 @@ std::shared_ptr<Display> createDisplay( Display::~Display() = default; void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) { - mId = args.id; + mIdVariant = args.idVariant; mPowerAdvisor = args.powerAdvisor; mHasPictureProcessing = args.hasPictureProcessing; mMaxLayerPictureProfiles = args.maxLayerPictureProfiles; @@ -67,7 +67,7 @@ bool Display::isValid() const { } DisplayId Display::getId() const { - return mId; + return asDisplayId(mIdVariant); } bool Display::isSecure() const { @@ -79,11 +79,15 @@ void Display::setSecure(bool secure) { } bool Display::isVirtual() const { - return mId.isVirtual(); + return !std::holds_alternative<PhysicalDisplayId>(mIdVariant); } ftl::Optional<DisplayId> Display::getDisplayId() const { - return mId; + return getId(); +} + +ftl::Optional<DisplayIdVariant> Display::getDisplayIdVariant() const { + return mIdVariant; } void Display::disconnect() { @@ -93,14 +97,14 @@ void Display::disconnect() { mIsDisconnected = true; - if (const auto id = HalDisplayId::tryCast(mId)) { + if (const auto id = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) { getCompositionEngine().getHwComposer().disconnectDisplay(*id); } } void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) { Output::setColorTransform(args); - const auto halDisplayId = HalDisplayId::tryCast(mId); + const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>); if (mIsDisconnected || !halDisplayId || CC_LIKELY(!args.colorTransformMatrix)) { return; } @@ -108,7 +112,7 @@ void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& auto& hwc = getCompositionEngine().getHwComposer(); status_t result = hwc.setColorTransform(*halDisplayId, *args.colorTransformMatrix); ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display \"%s\": %d", - to_string(mId).c_str(), result); + to_string(*halDisplayId).c_str(), result); } void Display::setColorProfile(const ColorProfile& colorProfile) { @@ -125,7 +129,7 @@ void Display::setColorProfile(const ColorProfile& colorProfile) { Output::setColorProfile(colorProfile); - const auto physicalId = PhysicalDisplayId::tryCast(mId); + const auto physicalId = getDisplayIdVariant().and_then(asPhysicalDisplayId); LOG_FATAL_IF(!physicalId); getCompositionEngine().getHwComposer().setActiveColorMode(*physicalId, colorProfile.mode, colorProfile.renderIntent); @@ -133,7 +137,7 @@ void Display::setColorProfile(const ColorProfile& colorProfile) { void Display::dump(std::string& out) const { const char* const type = isVirtual() ? "virtual" : "physical"; - base::StringAppendF(&out, "Display %s (%s, \"%s\")", to_string(mId).c_str(), type, + base::StringAppendF(&out, "Display %s (%s, \"%s\")", to_string(getId()).c_str(), type, getName().c_str()); out.append("\n Composition Display State:\n"); @@ -157,7 +161,7 @@ std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer( const sp<compositionengine::LayerFE>& layerFE) const { auto outputLayer = impl::createOutputLayer(*this, layerFE); - if (const auto halDisplayId = HalDisplayId::tryCast(mId); + if (const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>); outputLayer && !mIsDisconnected && halDisplayId) { auto& hwc = getCompositionEngine().getHwComposer(); auto hwcLayer = hwc.createLayer(*halDisplayId); @@ -171,8 +175,7 @@ std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer( void Display::setReleasedLayers(const compositionengine::CompositionRefreshArgs& refreshArgs) { Output::setReleasedLayers(refreshArgs); - if (mIsDisconnected || GpuVirtualDisplayId::tryCast(mId) || - refreshArgs.layersWithQueuedFrames.empty()) { + if (mIsDisconnected || isGpuVirtualDisplay() || refreshArgs.layersWithQueuedFrames.empty()) { return; } @@ -208,7 +211,7 @@ void Display::applyDisplayBrightness(bool applyImmediately) { if (!getState().displayBrightness) { return; } - if (auto displayId = PhysicalDisplayId::tryCast(mId)) { + if (auto displayId = getDisplayIdVariant().and_then(asPhysicalDisplayId)) { auto& hwc = getCompositionEngine().getHwComposer(); status_t result = hwc.setDisplayBrightness(*displayId, *getState().displayBrightness, getState().displayBrightnessNits, @@ -226,7 +229,7 @@ void Display::beginFrame() { Output::beginFrame(); // If we don't have a HWC display, then we are done. - const auto halDisplayId = HalDisplayId::tryCast(mId); + const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>); if (!halDisplayId) { return; } @@ -244,7 +247,7 @@ bool Display::chooseCompositionStrategy( } // If we don't have a HWC display, then we are done. - const auto halDisplayId = HalDisplayId::tryCast(mId); + const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>); if (!halDisplayId) { return false; } @@ -266,9 +269,9 @@ bool Display::chooseCompositionStrategy( } if (isPowerHintSessionEnabled()) { - mPowerAdvisor->setHwcValidateTiming(mId, hwcValidateStartTime, TimePoint::now()); - if (auto halDisplayId = HalDisplayId::tryCast(mId)) { - mPowerAdvisor->setSkippedValidate(mId, hwc.getValidateSkipped(*halDisplayId)); + mPowerAdvisor->setHwcValidateTiming(getId(), hwcValidateStartTime, TimePoint::now()); + if (auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) { + mPowerAdvisor->setSkippedValidate(*halDisplayId, hwc.getValidateSkipped(*halDisplayId)); } } @@ -292,7 +295,7 @@ void Display::applyCompositionStrategy(const std::optional<DeviceRequestedChange bool Display::getSkipColorTransform() const { auto& hwc = getCompositionEngine().getHwComposer(); - if (auto halDisplayId = HalDisplayId::tryCast(mId)) { + if (auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) { return hwc.hasDisplayCapability(*halDisplayId, DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM); } @@ -373,7 +376,7 @@ void Display::applyLayerLutsToLayers(const LayerLuts& layerLuts) { if (auto lutsIt = layerLuts.find(hwcLayer); lutsIt != layerLuts.end()) { if (auto mapperIt = mapper.find(hwcLayer); mapperIt != mapper.end()) { - layer->applyDeviceLayerLut(ndk::ScopedFileDescriptor(mapperIt->second.release()), + layer->applyDeviceLayerLut(::android::base::unique_fd(mapperIt->second.release()), lutsIt->second); } } @@ -383,7 +386,7 @@ void Display::applyLayerLutsToLayers(const LayerLuts& layerLuts) { } void Display::executeCommands() { - const auto halDisplayIdOpt = HalDisplayId::tryCast(mId); + const auto halDisplayIdOpt = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>); if (mIsDisconnected || !halDisplayIdOpt) { return; } @@ -394,7 +397,7 @@ void Display::executeCommands() { compositionengine::Output::FrameFences Display::presentFrame() { auto fences = impl::Output::presentFrame(); - const auto halDisplayIdOpt = HalDisplayId::tryCast(mId); + const auto halDisplayIdOpt = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>); if (mIsDisconnected || !halDisplayIdOpt) { return fences; } @@ -404,13 +407,13 @@ compositionengine::Output::FrameFences Display::presentFrame() { const TimePoint startTime = TimePoint::now(); if (isPowerHintSessionEnabled() && getState().earliestPresentTime) { - mPowerAdvisor->setHwcPresentDelayedTime(mId, *getState().earliestPresentTime); + mPowerAdvisor->setHwcPresentDelayedTime(*halDisplayIdOpt, *getState().earliestPresentTime); } hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime); if (isPowerHintSessionEnabled()) { - mPowerAdvisor->setHwcPresentTiming(mId, startTime, TimePoint::now()); + mPowerAdvisor->setHwcPresentTiming(*halDisplayIdOpt, startTime, TimePoint::now()); } fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt); @@ -433,8 +436,8 @@ compositionengine::Output::FrameFences Display::presentFrame() { void Display::setExpensiveRenderingExpected(bool enabled) { Output::setExpensiveRenderingExpected(enabled); - if (mPowerAdvisor && !GpuVirtualDisplayId::tryCast(mId)) { - mPowerAdvisor->setExpensiveRenderingExpected(mId, enabled); + if (mPowerAdvisor && !isGpuVirtualDisplay()) { + mPowerAdvisor->setExpensiveRenderingExpected(getId(), enabled); } } @@ -449,15 +452,15 @@ bool Display::isPowerHintSessionGpuReportingEnabled() { // For ADPF GPU v0 this is expected to set start time to when the GPU commands are submitted with // fence returned, i.e. when RenderEngine flushes the commands and returns the draw fence. void Display::setHintSessionGpuStart(TimePoint startTime) { - mPowerAdvisor->setGpuStartTime(mId, startTime); + mPowerAdvisor->setGpuStartTime(getId(), startTime); } void Display::setHintSessionGpuFence(std::unique_ptr<FenceTime>&& gpuFence) { - mPowerAdvisor->setGpuFenceTime(mId, std::move(gpuFence)); + mPowerAdvisor->setGpuFenceTime(getId(), std::move(gpuFence)); } void Display::setHintSessionRequiresRenderEngine(bool requiresRenderEngine) { - mPowerAdvisor->setRequiresRenderEngine(mId, requiresRenderEngine); + mPowerAdvisor->setRequiresRenderEngine(getId(), requiresRenderEngine); } const aidl::android::hardware::graphics::composer3::OverlayProperties* @@ -478,7 +481,7 @@ void Display::finishFrame(GpuCompositionResult&& result) { // 1) It is being handled by hardware composer, which may need this to // keep its virtual display state machine in sync, or // 2) There is work to be done (the dirty region isn't empty) - if (GpuVirtualDisplayId::tryCast(mId) && !mustRecompose()) { + if (isGpuVirtualDisplay() && !mustRecompose()) { ALOGV("Skipping display composition"); return; } @@ -487,7 +490,7 @@ void Display::finishFrame(GpuCompositionResult&& result) { } bool Display::supportsOffloadPresent() const { - if (auto halDisplayId = HalDisplayId::tryCast(mId)) { + if (auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) { auto& hwc = getCompositionEngine().getHwComposer(); return hwc.hasDisplayCapability(*halDisplayId, DisplayCapability::MULTI_THREADED_PRESENT); } diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index 734d76404e..25f64368a2 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -118,6 +118,10 @@ ftl::Optional<DisplayId> Output::getDisplayId() const { return {}; } +ftl::Optional<DisplayIdVariant> Output::getDisplayIdVariant() const { + return {}; +} + const std::string& Output::getName() const { return mName; } @@ -436,8 +440,8 @@ void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArg ftl::Future<std::monostate> Output::present( const compositionengine::CompositionRefreshArgs& refreshArgs) { const auto stringifyExpectedPresentTime = [this, &refreshArgs]() -> std::string { - return getDisplayId() - .and_then(PhysicalDisplayId::tryCast) + return getDisplayIdVariant() + .and_then(asPhysicalDisplayId) .and_then([&refreshArgs](PhysicalDisplayId id) { return refreshArgs.frameTargets.get(id); }) @@ -890,8 +894,8 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr return; } - if (auto frameTargetPtrOpt = getDisplayId() - .and_then(PhysicalDisplayId::tryCast) + if (auto frameTargetPtrOpt = getDisplayIdVariant() + .and_then(asPhysicalDisplayId) .and_then([&refreshArgs](PhysicalDisplayId id) { return refreshArgs.frameTargets.get(id); })) { @@ -1389,7 +1393,8 @@ std::optional<base::unique_fd> Output::composeSurfaces( // or complex GPU shaders and it's expensive. We boost the GPU frequency so that // GPU composition can finish in time. We must reset GPU frequency afterwards, // because high frequency consumes extra battery. - const bool expensiveRenderingExpected = + const bool expensiveBlurs = mLayerRequestingBackgroundBlur != nullptr; + const bool expensiveRenderingExpected = expensiveBlurs || std::any_of(clientCompositionLayers.begin(), clientCompositionLayers.end(), [outputDataspace = clientCompositionDisplay.outputDataspace](const auto& layer) { @@ -1564,7 +1569,9 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( .clearContent = !clientComposition, .blurSetting = blurSetting, .whitePointNits = layerState.whitePointNits, - .treat170mAsSrgb = outputState.treat170mAsSrgb}; + .treat170mAsSrgb = outputState.treat170mAsSrgb, + .luts = layer->getState().hwc ? layer->getState().hwc->luts + : nullptr}; if (auto clientCompositionSettings = layerFE.prepareClientComposition(targetSettings)) { clientCompositionLayers.push_back(std::move(*clientCompositionSettings)); @@ -1838,7 +1845,7 @@ void Output::applyPictureProfile() { if (!getDisplayId()) { return; } - if (auto displayId = PhysicalDisplayId::tryCast(*getDisplayId())) { + if (auto displayId = getDisplayIdVariant().and_then(asPhysicalDisplayId)) { auto& hwc = getCompositionEngine().getHwComposer(); const status_t error = hwc.setDisplayPictureProfileHandle(*displayId, getState().pictureProfileHandle); diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp index 96b86d5a31..ea360115c1 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp @@ -369,8 +369,11 @@ void OutputLayer::updateCompositionState( layerFEState->buffer->getPixelFormat())) : std::nullopt; - auto hdrRenderType = - getHdrRenderType(outputState.dataspace, pixelFormat, layerFEState->desiredHdrSdrRatio); + // prefer querying this from gralloc instead to catch 2094-10 metadata + const bool hasHdrMetadata = layerFEState->hdrMetadata.validTypes != 0; + + auto hdrRenderType = getHdrRenderType(outputState.dataspace, pixelFormat, + layerFEState->desiredHdrSdrRatio, hasHdrMetadata); // Determine the output dependent dataspace for this layer. If it is // colorspace agnostic, it just uses the dataspace chosen for the output to @@ -393,8 +396,8 @@ void OutputLayer::updateCompositionState( } // re-get HdrRenderType after the dataspace gets changed. - hdrRenderType = - getHdrRenderType(state.dataspace, pixelFormat, layerFEState->desiredHdrSdrRatio); + hdrRenderType = getHdrRenderType(state.dataspace, pixelFormat, layerFEState->desiredHdrSdrRatio, + hasHdrMetadata); // For hdr content, treat the white point as the display brightness - HDR content should not be // boosted or dimmed. @@ -416,12 +419,20 @@ void OutputLayer::updateCompositionState( state.dimmingRatio = std::min(idealizedMaxHeadroom / deviceHeadroom, 1.0f); state.whitePointNits = getOutput().getState().displayBrightnessNits * state.dimmingRatio; } else { + const bool isLayerFp16 = pixelFormat && *pixelFormat == ui::PixelFormat::RGBA_FP16; float layerBrightnessNits = getOutput().getState().sdrWhitePointNits; // RANGE_EXTENDED can "self-promote" to HDR, but is still rendered for a particular // range that we may need to re-adjust to the current display conditions + // Do NOT do this when we may render fp16 to an fp16 client target, to avoid applying + // and additional gain to the layer. This is because the fp16 client target should + // already be adapted to remap 1.0 to the SDR white point in the panel's luminance + // space. if (hdrRenderType == HdrRenderType::DISPLAY_HDR) { - layerBrightnessNits *= layerFEState->currentHdrSdrRatio; + if (!FlagManager::getInstance().fp16_client_target() || !isLayerFp16) { + layerBrightnessNits *= layerFEState->currentHdrSdrRatio; + } } + state.dimmingRatio = std::clamp(layerBrightnessNits / getOutput().getState().displayBrightnessNits, 0.f, 1.f); @@ -502,6 +513,15 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t editState().hwc->stateOverridden = isOverridden; editState().hwc->layerSkipped = skipLayer; + + + // Save the final HWC state for debugging purposes, e.g. perfetto tracing, dumpsys. + getLayerFE().setLastHwcState({.lastCompositionType = editState().hwc->hwcCompositionType, + .wasSkipped = skipLayer, + .wasOverridden = isOverridden, + .overrideBufferId = editState().overrideInfo.buffer + ? editState().overrideInfo.buffer.get()->getId() + : 0}); } void OutputLayer::writeOutputDependentGeometryStateToHWC(HWC2::Layer* hwcLayer, @@ -610,7 +630,7 @@ void OutputLayer::writeLutToHWC(HWC2::Layer* hwcLayer, lutProperties[i].samplingKey)}}); } - luts.pfd = ndk::ScopedFileDescriptor(dup(lutFileDescriptor.get())); + luts.pfd.set(dup(lutFileDescriptor.get())); luts.offsets = lutOffsets; luts.lutProperties = std::move(aidlProperties); } @@ -964,6 +984,13 @@ void OutputLayer::applyDeviceCompositionTypeChange(Composition compositionType) } hwcState.hwcCompositionType = compositionType; + + getLayerFE().setLastHwcState({.lastCompositionType = hwcState.hwcCompositionType, + .wasSkipped = hwcState.layerSkipped, + .wasOverridden = hwcState.stateOverridden, + .overrideBufferId = state.overrideInfo.buffer + ? state.overrideInfo.buffer.get()->getId() + : 0}); } void OutputLayer::prepareForDeviceLayerRequests() { @@ -986,7 +1013,7 @@ void OutputLayer::applyDeviceLayerRequest(hal::LayerRequest request) { } void OutputLayer::applyDeviceLayerLut( - ndk::ScopedFileDescriptor lutFileDescriptor, + ::android::base::unique_fd lutFd, std::vector<std::pair<int, LutProperties>> lutOffsetsAndProperties) { auto& state = editState(); LOG_FATAL_IF(!state.hwc); @@ -1005,9 +1032,9 @@ void OutputLayer::applyDeviceLayerLut( samplingKeys.emplace_back(static_cast<int32_t>(properties.samplingKeys[0])); } } - hwcState.luts = std::make_shared<gui::DisplayLuts>(base::unique_fd(lutFileDescriptor.release()), - std::move(offsets), std::move(dimensions), - std::move(sizes), std::move(samplingKeys)); + hwcState.luts = std::make_shared<gui::DisplayLuts>(std::move(lutFd), std::move(offsets), + std::move(dimensions), std::move(sizes), + std::move(samplingKeys)); } bool OutputLayer::needsFiltering() const { diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp index 783209c26a..2081cd5400 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp @@ -243,17 +243,9 @@ void Flattener::resetActivities(NonBufferHash hash, time_point now) { mCurrentGeometry = hash; mLastGeometryUpdate = now; - - for (const CachedSet& cachedSet : mLayers) { - if (cachedSet.getLayerCount() > 1) { - ++mInvalidatedCachedSetAges[cachedSet.getAge()]; - } - } - mLayers.clear(); if (mNewCachedSet) { - ++mInvalidatedCachedSetAges[mNewCachedSet->getAge()]; mNewCachedSet = std::nullopt; } } @@ -312,7 +304,6 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers mNewCachedSet->getFirstLayer().getState()->getId() == (*incomingLayerIter)->getId()) { if (mNewCachedSet->hasBufferUpdate()) { ALOGV("[%s] Dropping new cached set", __func__); - ++mInvalidatedCachedSetAges[0]; mNewCachedSet = std::nullopt; } else if (mNewCachedSet->hasReadyBuffer()) { ALOGV("[%s] Found ready buffer", __func__); @@ -325,6 +316,7 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers priorBlurLayer == (*incomingLayerIter)->getOutputLayer(); OutputLayer::CompositionState& state = (*incomingLayerIter)->getOutputLayer()->editState(); + state.overrideInfo = { .buffer = mNewCachedSet->getBuffer(), .acquireFence = mNewCachedSet->getDrawFence(), @@ -338,10 +330,6 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers }; ++incomingLayerIter; } - - if (currentLayerIter->getLayerCount() > 1) { - ++mInvalidatedCachedSetAges[currentLayerIter->getAge()]; - } ++currentLayerIter; skipCount -= layerCount; @@ -378,9 +366,9 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers }; ++incomingLayerIter; } + priorBlurLayer = currentLayerIter->getBlurLayer(); } else if (currentLayerIter->getLayerCount() > 1) { // Break the current layer into its constituent layers - ++mInvalidatedCachedSetAges[currentLayerIter->getAge()]; for (CachedSet& layer : currentLayerIter->decompose()) { bool disableBlur = priorBlurLayer && priorBlurLayer == (*incomingLayerIter)->getOutputLayer(); @@ -400,8 +388,8 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers currentLayerIter->updateAge(now); merged.emplace_back(*currentLayerIter); ++incomingLayerIter; + priorBlurLayer = currentLayerIter->getBlurLayer(); } - priorBlurLayer = currentLayerIter->getBlurLayer(); ++currentLayerIter; } diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp index 3e0c390a5d..48d02423f8 100644 --- a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp @@ -43,6 +43,10 @@ using ::testing::ReturnRef; using ::testing::SaveArg; using ::testing::StrictMock; +static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(123u); +static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(234u); +static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(567u); + struct CompositionEngineTest : public testing::Test { std::shared_ptr<TimeStats> mTimeStats; @@ -52,6 +56,26 @@ struct CompositionEngineTest : public testing::Test { std::shared_ptr<mock::Output> mOutput1{std::make_shared<StrictMock<mock::Output>>()}; std::shared_ptr<mock::Output> mOutput2{std::make_shared<StrictMock<mock::Output>>()}; std::shared_ptr<mock::Output> mOutput3{std::make_shared<StrictMock<mock::Output>>()}; + + std::array<impl::OutputCompositionState, 3> mOutputStates; + + void SetUp() override { + EXPECT_CALL(*mOutput1, getDisplayId) + .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId1))); + EXPECT_CALL(*mOutput2, getDisplayId) + .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId2))); + EXPECT_CALL(*mOutput3, getDisplayId) + .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId3))); + + // Most tests will depend on the outputs being enabled. + for (auto& state : mOutputStates) { + state.isEnabled = true; + } + + EXPECT_CALL(*mOutput1, getState).WillRepeatedly(ReturnRef(mOutputStates[0])); + EXPECT_CALL(*mOutput2, getState).WillRepeatedly(ReturnRef(mOutputStates[1])); + EXPECT_CALL(*mOutput3, getState).WillRepeatedly(ReturnRef(mOutputStates[2])); + } }; TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) { @@ -61,7 +85,7 @@ TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) { TEST_F(CompositionEngineTest, canSetHWComposer) { android::mock::HWComposer* hwc = new StrictMock<android::mock::HWComposer>(); - mEngine.setHwComposer(std::unique_ptr<android::HWComposer>(hwc)); + mEngine.setHwComposer(static_cast<android::HWComposer*>(hwc)); EXPECT_EQ(hwc, &mEngine.getHwComposer()); } @@ -94,7 +118,7 @@ struct CompositionEnginePresentTest : public CompositionEngineTest { StrictMock<CompositionEnginePartialMock> mEngine; }; -TEST_F(CompositionEnginePresentTest, worksWithEmptyRequest) { +TEST_F(CompositionEnginePresentTest, zeroOutputs) { // present() always calls preComposition() and postComposition() EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs))); EXPECT_CALL(mEngine, postComposition(Ref(mRefreshArgs))); @@ -102,7 +126,7 @@ TEST_F(CompositionEnginePresentTest, worksWithEmptyRequest) { mEngine.present(mRefreshArgs); } -TEST_F(CompositionEnginePresentTest, worksAsExpected) { +TEST_F(CompositionEnginePresentTest, threeOutputs) { // Expect calls to in a certain sequence InSequence seq; @@ -114,9 +138,7 @@ TEST_F(CompositionEnginePresentTest, worksAsExpected) { EXPECT_CALL(*mOutput2, prepare(Ref(mRefreshArgs), _)); EXPECT_CALL(*mOutput3, prepare(Ref(mRefreshArgs), _)); - // All of mOutput<i> are StrictMocks. If the flag is true, it will introduce - // calls to getDisplayId, which are not relevant to this test. - SET_FLAG_FOR_TEST(flags::multithreaded_present, false); + EXPECT_CALL(*mOutput1, supportsOffloadPresent).WillOnce(Return(false)); // The last step is to actually present each output. EXPECT_CALL(*mOutput1, present(Ref(mRefreshArgs))) @@ -284,8 +306,6 @@ struct CompositionEngineOffloadTest : public testing::Test { std::shared_ptr<mock::Output> mVirtualDisplay{std::make_shared<StrictMock<mock::Output>>()}; std::shared_ptr<mock::Output> mHalVirtualDisplay{std::make_shared<StrictMock<mock::Output>>()}; - static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(123u); - static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(234u); static constexpr GpuVirtualDisplayId kGpuVirtualDisplayId{789u}; static constexpr HalVirtualDisplayId kHalVirtualDisplayId{456u}; @@ -294,12 +314,23 @@ struct CompositionEngineOffloadTest : public testing::Test { void SetUp() override { EXPECT_CALL(*mDisplay1, getDisplayId) .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId1))); + EXPECT_CALL(*mDisplay1, getDisplayIdVariant).WillRepeatedly(Return(kDisplayId1)); + EXPECT_CALL(*mDisplay2, getDisplayId) .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId2))); + EXPECT_CALL(*mDisplay2, getDisplayIdVariant).WillRepeatedly(Return(kDisplayId2)); + EXPECT_CALL(*mVirtualDisplay, getDisplayId) .WillRepeatedly(Return(std::make_optional<DisplayId>(kGpuVirtualDisplayId))); + const DisplayIdVariant gpuVariant = + GpuVirtualDisplayId::fromValue(kGpuVirtualDisplayId.value); + EXPECT_CALL(*mVirtualDisplay, getDisplayIdVariant).WillRepeatedly(Return(gpuVariant)); + EXPECT_CALL(*mHalVirtualDisplay, getDisplayId) .WillRepeatedly(Return(std::make_optional<DisplayId>(kHalVirtualDisplayId))); + const DisplayIdVariant halVariant = + HalVirtualDisplayId::fromValue(kHalVirtualDisplayId.value); + EXPECT_CALL(*mHalVirtualDisplay, getDisplayIdVariant).WillRepeatedly(Return(halVariant)); // Most tests will depend on the outputs being enabled. for (auto& state : mOutputStates) { @@ -332,7 +363,6 @@ TEST_F(CompositionEngineOffloadTest, basic) { EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1); EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); setOutputs({mDisplay1, mDisplay2}); mEngine.present(mRefreshArgs); @@ -345,7 +375,6 @@ TEST_F(CompositionEngineOffloadTest, dependsOnSupport) { EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0); EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); setOutputs({mDisplay1, mDisplay2}); mEngine.present(mRefreshArgs); @@ -358,20 +387,6 @@ TEST_F(CompositionEngineOffloadTest, dependsOnSupport2) { EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0); EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); - setOutputs({mDisplay1, mDisplay2}); - - mEngine.present(mRefreshArgs); -} - -TEST_F(CompositionEngineOffloadTest, dependsOnFlag) { - EXPECT_CALL(*mDisplay1, supportsOffloadPresent).Times(0); - EXPECT_CALL(*mDisplay2, supportsOffloadPresent).Times(0); - - EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0); - EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0); - - SET_FLAG_FOR_TEST(flags::multithreaded_present, false); setOutputs({mDisplay1, mDisplay2}); mEngine.present(mRefreshArgs); @@ -382,7 +397,6 @@ TEST_F(CompositionEngineOffloadTest, oneDisplay) { EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); setOutputs({mDisplay1}); mEngine.present(mRefreshArgs); @@ -397,7 +411,6 @@ TEST_F(CompositionEngineOffloadTest, virtualDisplay) { EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0); EXPECT_CALL(*mVirtualDisplay, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); setOutputs({mDisplay1, mDisplay2, mVirtualDisplay}); mEngine.present(mRefreshArgs); @@ -410,7 +423,6 @@ TEST_F(CompositionEngineOffloadTest, virtualDisplay2) { EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0); EXPECT_CALL(*mVirtualDisplay, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); setOutputs({mDisplay1, mVirtualDisplay}); mEngine.present(mRefreshArgs); @@ -423,7 +435,6 @@ TEST_F(CompositionEngineOffloadTest, halVirtual) { EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1); EXPECT_CALL(*mHalVirtualDisplay, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); setOutputs({mDisplay1, mHalVirtualDisplay}); mEngine.present(mRefreshArgs); @@ -440,7 +451,6 @@ TEST_F(CompositionEngineOffloadTest, ordering) { EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1); EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); setOutputs({mVirtualDisplay, mHalVirtualDisplay, mDisplay1, mDisplay2}); mEngine.present(mRefreshArgs); @@ -458,7 +468,6 @@ TEST_F(CompositionEngineOffloadTest, dependsOnEnabled) { EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0); EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); setOutputs({mDisplay1, mDisplay2}); mEngine.present(mRefreshArgs); @@ -478,7 +487,6 @@ TEST_F(CompositionEngineOffloadTest, disabledDisplaysDoNotPreventOthersFromOfflo EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0); EXPECT_CALL(*mHalVirtualDisplay, offloadPresentNextFrame).Times(0); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); setOutputs({mDisplay1, mDisplay2, mHalVirtualDisplay}); mEngine.present(mRefreshArgs); diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp index c1e59d01de..77fd4466ef 100644 --- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp @@ -278,7 +278,7 @@ TEST_F(DisplayCreationTest, createGpuVirtualDisplay) { impl::createDisplay(mCompositionEngine, getDisplayCreationArgsForGpuVirtualDisplay()); EXPECT_FALSE(display->isSecure()); EXPECT_TRUE(display->isVirtual()); - EXPECT_TRUE(GpuVirtualDisplayId::tryCast(display->getId())); + EXPECT_TRUE(display->getDisplayIdVariant().and_then(asDisplayIdOfType<GpuVirtualDisplayId>)); } /* @@ -318,6 +318,7 @@ TEST_F(DisplaySetConfigurationTest, configuresHalVirtualDisplay) { EXPECT_EQ(HAL_VIRTUAL_DISPLAY_ID, mDisplay->getId()); EXPECT_FALSE(mDisplay->isSecure()); EXPECT_TRUE(mDisplay->isVirtual()); + EXPECT_TRUE(mDisplay->getDisplayIdVariant().and_then(asDisplayIdOfType<HalVirtualDisplayId>)); EXPECT_FALSE(mDisplay->isValid()); const auto& filter = mDisplay->getState().layerFilter; @@ -337,6 +338,7 @@ TEST_F(DisplaySetConfigurationTest, configuresGpuVirtualDisplay) { EXPECT_EQ(GPU_VIRTUAL_DISPLAY_ID, mDisplay->getId()); EXPECT_FALSE(mDisplay->isSecure()); EXPECT_TRUE(mDisplay->isVirtual()); + EXPECT_TRUE(mDisplay->getDisplayIdVariant().and_then(asDisplayIdOfType<GpuVirtualDisplayId>)); EXPECT_FALSE(mDisplay->isValid()); const auto& filter = mDisplay->getState().layerFilter; @@ -572,7 +574,7 @@ TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfGpuDisplay) { auto args = getDisplayCreationArgsForGpuVirtualDisplay(); std::shared_ptr<Display> gpuDisplay = createPartialMockDisplay<Display>(mCompositionEngine, args); - EXPECT_TRUE(GpuVirtualDisplayId::tryCast(gpuDisplay->getId())); + EXPECT_TRUE(gpuDisplay->getDisplayIdVariant().and_then(asDisplayIdOfType<GpuVirtualDisplayId>)); chooseCompositionStrategy(gpuDisplay.get()); diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index 09ad9fa497..b56147acd9 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -148,20 +148,23 @@ struct OutputTest : public testing::Test { virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0; virtual ftl::Optional<DisplayId> getDisplayId() const override { return mId; } + virtual ftl::Optional<DisplayIdVariant> getDisplayIdVariant() const override { + return DisplayIdVariant(mId); + } virtual bool hasPictureProcessing() const override { return mHasPictureProcessing; } virtual int32_t getMaxLayerPictureProfiles() const override { return mMaxLayerPictureProfiles; } - void setDisplayIdForTest(DisplayId value) { mId = value; } + void setDisplayIdForTest(PhysicalDisplayId value) { mId = value; } void setHasPictureProcessingForTest(bool value) { mHasPictureProcessing = value; } void setMaxLayerPictureProfilesForTest(int32_t value) { mMaxLayerPictureProfiles = value; } private: - ftl::Optional<DisplayId> mId; + PhysicalDisplayId mId; bool mHasPictureProcessing; int32_t mMaxLayerPictureProfiles; }; diff --git a/services/surfaceflinger/Display/DisplayModeController.cpp b/services/surfaceflinger/Display/DisplayModeController.cpp index a086aee847..87a677cd58 100644 --- a/services/surfaceflinger/Display/DisplayModeController.cpp +++ b/services/surfaceflinger/Display/DisplayModeController.cpp @@ -97,9 +97,7 @@ auto DisplayModeController::setDesiredMode(PhysicalDisplayId displayId, const bool force = desiredModeOpt->force; desiredModeOpt = std::move(desiredMode); desiredModeOpt->emitEvent |= emitEvent; - if (FlagManager::getInstance().connected_display()) { - desiredModeOpt->force |= force; - } + desiredModeOpt->force |= force; return DesiredModeAction::None; } @@ -191,7 +189,7 @@ auto DisplayModeController::initiateModeChange( // cleared until the next `SF::initiateDisplayModeChanges`. However, the desired mode has been // consumed at this point, so clear the `force` flag to prevent an endless loop of // `initiateModeChange`. - if (FlagManager::getInstance().connected_display()) { + { std::scoped_lock lock(displayPtr->desiredModeLock); if (displayPtr->desiredModeOpt) { displayPtr->desiredModeOpt->force = false; diff --git a/services/surfaceflinger/Display/DisplayModeRequest.h b/services/surfaceflinger/Display/DisplayModeRequest.h index ec3ec526a1..2e9dc1e34e 100644 --- a/services/surfaceflinger/Display/DisplayModeRequest.h +++ b/services/surfaceflinger/Display/DisplayModeRequest.h @@ -26,7 +26,8 @@ namespace android::display { struct DisplayModeRequest { scheduler::FrameRateMode mode; - // Whether to emit DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE. + // Whether to emit DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE for a change in refresh rate + // or render rate. Ignored for resolution changes, which always emit the event. bool emitEvent = false; // Whether to force the request to be applied, even if the mode is unchanged. diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index c743ea2ff4..bad5e2e3b5 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -26,7 +26,6 @@ #include <common/trace.h> #include <compositionengine/CompositionEngine.h> -#include <compositionengine/Display.h> #include <compositionengine/DisplayColorProfile.h> #include <compositionengine/DisplayColorProfileCreationArgs.h> #include <compositionengine/DisplayCreationArgs.h> @@ -51,6 +50,17 @@ namespace android { namespace hal = hardware::graphics::composer::hal; +namespace gui { +inline std::string_view to_string(ISurfaceComposer::OptimizationPolicy optimizationPolicy) { + switch (optimizationPolicy) { + case ISurfaceComposer::OptimizationPolicy::optimizeForPower: + return "optimizeForPower"; + case ISurfaceComposer::OptimizationPolicy::optimizeForPerformance: + return "optimizeForPerformance"; + } +} +} // namespace gui + DisplayDeviceCreationArgs::DisplayDeviceCreationArgs( const sp<SurfaceFlinger>& flinger, HWComposer& hwComposer, const wp<IBinder>& displayToken, std::shared_ptr<compositionengine::Display> compositionDisplay) @@ -169,8 +179,7 @@ auto DisplayDevice::getFrontEndInfo() const -> frontend::DisplayInfo { } void DisplayDevice::setPowerMode(hal::PowerMode mode) { - // TODO(b/241285876): Skip this for virtual displays. - if (mode == hal::PowerMode::OFF || mode == hal::PowerMode::ON) { + if (!isVirtual() && (mode == hal::PowerMode::OFF || mode == hal::PowerMode::ON)) { if (mStagedBrightness && mBrightness != mStagedBrightness) { getCompositionDisplay()->setNextBrightness(*mStagedBrightness); mBrightness = *mStagedBrightness; @@ -223,9 +232,7 @@ void DisplayDevice::setFlags(uint32_t flags) { mFlags = flags; } -void DisplayDevice::setDisplaySize(int width, int height) { - LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays."); - const auto size = ui::Size(width, height); +void DisplayDevice::setDisplaySize(ui::Size size) { mCompositionDisplay->setDisplaySize(size); if (mRefreshRateOverlay) { mRefreshRateOverlay->setViewport(size); @@ -285,6 +292,7 @@ void DisplayDevice::dump(utils::Dumper& dumper) const { dumper.dump("name"sv, '"' + mDisplayName + '"'); dumper.dump("powerMode"sv, mPowerMode); + dumper.dump("optimizationPolicy"sv, mOptimizationPolicy); if (mRefreshRateSelector) { mRefreshRateSelector->dump(dumper); @@ -299,6 +307,10 @@ DisplayId DisplayDevice::getId() const { return mCompositionDisplay->getId(); } +bool DisplayDevice::isVirtual() const { + return mCompositionDisplay->isVirtual(); +} + bool DisplayDevice::isSecure() const { return mCompositionDisplay->isSecure(); } @@ -307,6 +319,15 @@ void DisplayDevice::setSecure(bool secure) { mCompositionDisplay->setSecure(secure); } +gui::ISurfaceComposer::OptimizationPolicy DisplayDevice::getOptimizationPolicy() const { + return mOptimizationPolicy; +} + +void DisplayDevice::setOptimizationPolicy( + gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy) { + mOptimizationPolicy = optimizationPolicy; +} + const Rect DisplayDevice::getBounds() const { return mCompositionDisplay->getState().displaySpace.getBoundsAsRect(); } diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index af2b48fc07..7d7c8adb7b 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -23,6 +23,8 @@ #include <android-base/thread_annotations.h> #include <android/native_window.h> #include <binder/IBinder.h> +#include <compositionengine/Display.h> +#include <compositionengine/DisplaySurface.h> #include <gui/LayerState.h> #include <math/mat4.h> #include <renderengine/RenderEngine.h> @@ -61,11 +63,6 @@ class SurfaceFlinger; struct CompositionInfo; struct DisplayDeviceCreationArgs; -namespace compositionengine { -class Display; -class DisplaySurface; -} // namespace compositionengine - namespace display { class DisplaySnapshot; } // namespace display @@ -85,7 +82,7 @@ public: return mCompositionDisplay; } - bool isVirtual() const { return getId().isVirtual(); } + bool isVirtual() const; bool isPrimary() const { return mIsPrimary; } // isSecure indicates whether this display can be trusted to display @@ -93,12 +90,17 @@ public: bool isSecure() const; void setSecure(bool secure); + // The optimization policy influences whether this display is optimized for power or + // performance. + gui::ISurfaceComposer::OptimizationPolicy getOptimizationPolicy() const; + void setOptimizationPolicy(gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy); + int getWidth() const; int getHeight() const; ui::Size getSize() const { return {getWidth(), getHeight()}; } void setLayerFilter(ui::LayerFilter); - void setDisplaySize(int width, int height); + void setDisplaySize(ui::Size); void setProjection(ui::Rotation orientation, Rect viewport, Rect frame); void stageBrightness(float brightness) REQUIRES(kMainThreadContext); void persistBrightness(bool needsComposite) REQUIRES(kMainThreadContext); @@ -118,17 +120,30 @@ public: DisplayId getId() const; + DisplayIdVariant getDisplayIdVariant() const { + const auto idVariant = mCompositionDisplay->getDisplayIdVariant(); + LOG_FATAL_IF(!idVariant); + return *idVariant; + } + + std::optional<VirtualDisplayIdVariant> getVirtualDisplayIdVariant() const { + return ftl::match( + getDisplayIdVariant(), + [](PhysicalDisplayId) { return std::optional<VirtualDisplayIdVariant>(); }, + [](auto id) { return std::optional<VirtualDisplayIdVariant>(id); }); + } + // Shorthand to upcast the ID of a display whose type is known as a precondition. PhysicalDisplayId getPhysicalId() const { - const auto id = PhysicalDisplayId::tryCast(getId()); - LOG_FATAL_IF(!id); - return *id; + const auto physicalDisplayId = asPhysicalDisplayId(getDisplayIdVariant()); + LOG_FATAL_IF(!physicalDisplayId); + return *physicalDisplayId; } VirtualDisplayId getVirtualId() const { - const auto id = VirtualDisplayId::tryCast(getId()); - LOG_FATAL_IF(!id); - return *id; + const auto virtualDisplayId = asVirtualDisplayId(getDisplayIdVariant()); + LOG_FATAL_IF(!virtualDisplayId); + return *virtualDisplayId; } const wp<IBinder>& getDisplayToken() const { return mDisplayToken; } @@ -236,6 +251,9 @@ private: // TODO(b/182939859): Remove special cases for primary display. const bool mIsPrimary; + gui::ISurfaceComposer::OptimizationPolicy mOptimizationPolicy = + gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance; + uint32_t mFlags = 0; // Requested refresh rate in fps, supported only for virtual displays. @@ -260,6 +278,7 @@ struct DisplayDeviceState { struct Physical { PhysicalDisplayId id; hardware::graphics::composer::hal::HWDisplayId hwcDisplayId; + uint8_t port; DisplayModePtr activeMode; bool operator==(const Physical& other) const { @@ -282,11 +301,16 @@ struct DisplayDeviceState { std::string displayName; std::string uniqueId; bool isSecure = false; + + gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy = + gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance; bool isProtected = false; // Refer to DisplayDevice::mRequestedRefreshRate, for virtual display only Fps requestedRefreshRate; int32_t maxLayerPictureProfiles = 0; bool hasPictureProcessing = false; + hardware::graphics::composer::hal::PowerMode initialPowerMode{ + hardware::graphics::composer::hal::PowerMode::OFF}; private: static std::atomic<int32_t> sNextSequenceId; diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp index 8529c72419..d547af98ea 100644 --- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp @@ -26,12 +26,15 @@ #include <android/binder_manager.h> #include <common/FlagManager.h> #include <common/trace.h> +#include <fmt/core.h> #include <log/log.h> #include <aidl/android/hardware/graphics/composer3/BnComposerCallback.h> #include <algorithm> #include <cinttypes> +#include <string> +#include <string_view> #include "HWC2.h" @@ -229,25 +232,32 @@ private: HWC2::ComposerCallback& mCallback; }; -std::string AidlComposer::instance(const std::string& serviceName) { - return std::string(AidlIComposer::descriptor) + "/" + serviceName; +std::string AidlComposer::ensureFullyQualifiedName(std::string_view serviceName) { + if (!serviceName.starts_with(AidlIComposer::descriptor)) { + return fmt::format("{}/{}", AidlIComposer::descriptor, serviceName); + } else { + return std::string{serviceName}; + } } -bool AidlComposer::isDeclared(const std::string& serviceName) { - return AServiceManager_isDeclared(instance(serviceName).c_str()); +bool AidlComposer::namesAnAidlComposerService(std::string_view serviceName) { + if (!serviceName.starts_with(AidlIComposer::descriptor)) { + return AServiceManager_isDeclared(ensureFullyQualifiedName(serviceName).c_str()); + } + return true; } AidlComposer::AidlComposer(const std::string& serviceName) { // This only waits if the service is actually declared - mAidlComposer = AidlIComposer::fromBinder( - ndk::SpAIBinder(AServiceManager_waitForService(instance(serviceName).c_str()))); + mAidlComposer = AidlIComposer::fromBinder(ndk::SpAIBinder( + AServiceManager_waitForService(ensureFullyQualifiedName(serviceName).c_str()))); if (!mAidlComposer) { LOG_ALWAYS_FATAL("Failed to get AIDL composer service"); return; } if (!mAidlComposer->createClient(&mAidlComposerClient).isOk()) { - LOG_ALWAYS_FATAL("Can't create AidlComposerClient, fallback to HIDL"); + LOG_ALWAYS_FATAL("Can't create AidlComposerClient"); return; } @@ -347,7 +357,9 @@ void AidlComposer::registerCallback(HWC2::ComposerCallback& callback) { mAidlComposerCallback = ndk::SharedRefBase::make<AidlIComposerCallbackWrapper>(callback); ndk::SpAIBinder binder = mAidlComposerCallback->asBinder(); - AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_FIFO, 2); + if (!FlagManager::getInstance().disable_sched_fifo_composer_callback()) { + AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_FIFO, 2); + } const auto status = mAidlComposerClient->registerCallback(mAidlComposerCallback); if (!status.isOk()) { @@ -686,6 +698,36 @@ Error AidlComposer::getReleaseFences(Display display, std::vector<Layer>* outLay return error; } +Error AidlComposer::getLayerPresentFences(Display display, std::vector<Layer>* outLayers, + std::vector<int>* outFences, + std::vector<int64_t>* outLatenciesNanos) { + Error error = Error::NONE; + std::vector<PresentFence::LayerPresentFence> fences; + { + mMutex.lock_shared(); + if (auto reader = getReader(display)) { + fences = reader->get().takeLayerPresentFences(translate<int64_t>(display)); + } else { + error = Error::BAD_DISPLAY; + } + mMutex.unlock_shared(); + } + + outLayers->reserve(fences.size()); + outFences->reserve(fences.size()); + outLatenciesNanos->reserve(fences.size()); + + for (auto& fence : fences) { + outLayers->emplace_back(translate<Layer>(fence.layer)); + // take ownership + const int fenceOwner = fence.bufferFence.get(); + *fence.bufferFence.getR() = -1; + outFences->emplace_back(fenceOwner); + outLatenciesNanos->emplace_back(fence.bufferLatencyNanos); + } + return error; +} + Error AidlComposer::presentDisplay(Display display, int* outPresentFence) { const auto displayId = translate<int64_t>(display); SFTRACE_FORMAT("HwcPresentDisplay %" PRId64, displayId); @@ -1731,7 +1773,6 @@ void AidlComposer::onHotplugDisconnect(Display display) { } bool AidlComposer::hasMultiThreadedPresentSupport(Display display) { - if (!FlagManager::getInstance().multithreaded_present()) return false; const auto displayId = translate<int64_t>(display); std::vector<AidlDisplayCapability> capabilities; const auto status = mAidlComposerClient->getDisplayCapabilities(displayId, &capabilities); diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h index 82006f407b..5fcc8b00ba 100644 --- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h @@ -24,7 +24,7 @@ #include <functional> #include <optional> #include <string> -#include <utility> +#include <string_view> #include <vector> #include <android/hardware/graphics/composer/2.4/IComposer.h> @@ -53,7 +53,8 @@ class AidlIComposerCallbackWrapper; // Composer is a wrapper to IComposer, a proxy to server-side composer. class AidlComposer final : public Hwc2::Composer { public: - static bool isDeclared(const std::string& serviceName); + // Returns true if serviceName appears to be something that is meant to be used by AidlComposer. + static bool namesAnAidlComposerService(std::string_view serviceName); explicit AidlComposer(const std::string& serviceName); ~AidlComposer() override; @@ -106,6 +107,10 @@ public: Error getReleaseFences(Display display, std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences) override; + Error getLayerPresentFences(Display display, std::vector<Layer>* outLayers, + std::vector<int>* outFences, + std::vector<int64_t>* outLatenciesNanos) override; + Error presentDisplay(Display display, int* outPresentFence) override; Error setActiveConfig(Display display, Config config) override; @@ -254,8 +259,8 @@ private: // this function to execute the command queue. Error execute(Display) REQUIRES_SHARED(mMutex); - // returns the default instance name for the given service - static std::string instance(const std::string& serviceName); + // Ensures serviceName is fully qualified. + static std::string ensureFullyQualifiedName(std::string_view serviceName); ftl::Optional<std::reference_wrapper<ComposerClientWriter>> getWriter(Display) REQUIRES_SHARED(mMutex); diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index d69a923b4e..1e4132cfc6 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -26,7 +26,7 @@ namespace android::Hwc2 { Composer::~Composer() = default; std::unique_ptr<Composer> Composer::create(const std::string& serviceName) { - if (AidlComposer::isDeclared(serviceName)) { + if (AidlComposer::namesAnAidlComposerService(serviceName)) { return std::make_unique<AidlComposer>(serviceName); } diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 6e431bb878..018ee6e461 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -157,6 +157,10 @@ public: virtual Error getReleaseFences(Display display, std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences) = 0; + virtual Error getLayerPresentFences(Display display, std::vector<Layer>* outLayers, + std::vector<int>* outFences, + std::vector<int64_t>* outLatenciesNanos) = 0; + virtual Error presentDisplay(Display display, int* outPresentFence) = 0; virtual Error setActiveConfig(Display display, Config config) = 0; diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index e63a14bb5e..8d16a6bbb3 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -439,11 +439,8 @@ Error Display::setActiveConfigWithConstraints(hal::HWConfigId configId, // FIXME (b/319505580): At least the first config set on an external display must be // `setActiveConfig`, so skip over the block that calls `setActiveConfigWithConstraints` // for simplicity. - const bool connected_display = FlagManager::getInstance().connected_display(); - if (isVsyncPeriodSwitchSupported() && - (!connected_display || - getConnectionType().value_opt() != ui::DisplayConnectionType::External)) { + getConnectionType().value_opt() != ui::DisplayConnectionType::External) { Hwc2::IComposerClient::VsyncPeriodChangeConstraints hwc2Constraints; hwc2Constraints.desiredTimeNanos = constraints.desiredTimeNanos; hwc2Constraints.seamlessRequired = constraints.seamlessRequired; @@ -638,9 +635,17 @@ Error Display::getRequestedLuts(LayerLuts* outLuts, [](int32_t i, LutProperties j) { return std::make_pair(i, j); }); outLuts->emplace_or_replace(layer.get(), lutOffsetsAndProperties); lutFileDescriptorMapper.emplace_or_replace(layer.get(), - ndk::ScopedFileDescriptor( + ::android::base::unique_fd( layerLut.luts.pfd.release())); + } else { + ALOGE("getRequestedLuts: invalid luts on layer %" PRIu64 " found" + " on display %" PRIu64 ". pfd.get()=%d, offsets.has_value()=%d", + layerIds[i], mId, layerLut.luts.pfd.get(), layerLut.luts.offsets.has_value()); } + } else { + ALOGE("getRequestedLuts: invalid layer %" PRIu64 " found" + " on display %" PRIu64, + layerIds[i], mId); } } diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index c3deb8429a..7c1f8e3da0 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -115,7 +115,7 @@ public: using LayerLuts = ftl::SmallMap<HWC2::Layer*, LutOffsetAndProperties, kLutFileDescriptorMapperSize>; using LutFileDescriptorMapper = - ftl::SmallMap<HWC2::Layer*, ndk::ScopedFileDescriptor, kLutFileDescriptorMapperSize>; + ftl::SmallMap<HWC2::Layer*, ::android::base::unique_fd, kLutFileDescriptorMapperSize>; [[nodiscard]] virtual hal::Error acceptChanges() = 0; [[nodiscard]] virtual base::expected<std::shared_ptr<HWC2::Layer>, hal::Error> diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 7f94428617..14088a6428 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -138,14 +138,14 @@ bool HWComposer::hasDisplayCapability(HalDisplayId displayId, DisplayCapability } std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hal::HWDisplayId hwcDisplayId, - hal::Connection connection) { - switch (connection) { - case hal::Connection::CONNECTED: + HotplugEvent event) { + switch (event) { + case HotplugEvent::Connected: return onHotplugConnect(hwcDisplayId); - case hal::Connection::DISCONNECTED: + case HotplugEvent::Disconnected: return onHotplugDisconnect(hwcDisplayId); - case hal::Connection::INVALID: - return {}; + case HotplugEvent::LinkUnstable: + return onHotplugLinkTrainingFailure(hwcDisplayId); } } @@ -225,7 +225,11 @@ bool HWComposer::allocateVirtualDisplay(HalVirtualDisplayId displayId, ui::Size } void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, PhysicalDisplayId displayId, - std::optional<ui::Size> physicalSize) { + uint8_t port, std::optional<ui::Size> physicalSize) { + LOG_ALWAYS_FATAL_IF(!mActivePorts.try_emplace(port).second, + "Cannot attach display %" PRIu64 " to an already active port %" PRIu8 ".", + hwcDisplayId, port); + mPhysicalDisplayIdMap[hwcDisplayId] = displayId; if (!mPrimaryHwcDisplayId) { @@ -239,6 +243,7 @@ void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, Physical newDisplay->setConnected(true); newDisplay->setPhysicalSizeInMm(physicalSize); displayData.hwcDisplay = std::move(newDisplay); + displayData.port = port; } int32_t HWComposer::getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId, @@ -758,6 +763,9 @@ void HWComposer::disconnectDisplay(HalDisplayId displayId) { const auto hwcDisplayId = displayData.hwcDisplay->getId(); mPhysicalDisplayIdMap.erase(hwcDisplayId); + if (const auto port = displayData.port) { + mActivePorts.erase(port.value()); + } mDisplayData.erase(displayId); // Reset the primary display ID if we're disconnecting it. @@ -1060,7 +1068,7 @@ const std::unordered_map<std::string, bool>& HWComposer::getSupportedLayerGeneri return mSupportedLayerGenericMetadata; } -ftl::SmallMap<HWC2::Layer*, ndk::ScopedFileDescriptor, 20>& +ftl::SmallMap<HWC2::Layer*, ::android::base::unique_fd, 20>& HWComposer::getLutFileDescriptorMapper() { return mLutFileDescriptorMapper; } @@ -1123,8 +1131,15 @@ std::optional<hal::HWDisplayId> HWComposer::fromPhysicalDisplayId( return {}; } -bool HWComposer::shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId, +bool HWComposer::shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId, uint8_t port, bool hasDisplayIdentificationData) const { + if (mActivePorts.contains(port)) { + ALOGE("Ignoring connection of display %" PRIu64 ". Port %" PRIu8 + " is already in active use.", + hwcDisplayId, port); + return true; + } + if (mHasMultiDisplaySupport && !hasDisplayIdentificationData) { ALOGE("Ignoring connection of display %" PRIu64 " without identification data", hwcDisplayId); @@ -1170,7 +1185,7 @@ std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect( mHasMultiDisplaySupport ? "generalized" : "legacy"); } - if (shouldIgnoreHotplugConnect(hwcDisplayId, hasDisplayIdentificationData)) { + if (shouldIgnoreHotplugConnect(hwcDisplayId, port, hasDisplayIdentificationData)) { return {}; } @@ -1202,7 +1217,7 @@ std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect( if (info->preferredDetailedTimingDescriptor) { size = info->preferredDetailedTimingDescriptor->physicalSizeInMm; } - allocatePhysicalDisplay(hwcDisplayId, info->id, size); + allocatePhysicalDisplay(hwcDisplayId, info->id, info->port, size); } return info; } @@ -1230,6 +1245,16 @@ std::optional<DisplayIdentificationInfo> HWComposer::onHotplugDisconnect( return DisplayIdentificationInfo{.id = *displayId}; } +std::optional<DisplayIdentificationInfo> HWComposer::onHotplugLinkTrainingFailure( + hal::HWDisplayId hwcDisplayId) { + const auto displayId = toPhysicalDisplayId(hwcDisplayId); + if (!displayId) { + LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display"); + return {}; + } + return DisplayIdentificationInfo{.id = *displayId}; +} + void HWComposer::loadCapabilities() { static_assert(sizeof(hal::Capability) == sizeof(int32_t), "Capability size has changed"); auto capabilities = mComposer->getCapabilities(); diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index b1b997a197..472411cf99 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -28,6 +28,7 @@ #include <ftl/expected.h> #include <ftl/future.h> #include <ui/DisplayIdentification.h> +#include <ui/DisplayMap.h> #include <ui/FenceTime.h> #include <ui/PictureProfileHandle.h> @@ -144,7 +145,7 @@ public: // supported by the HWC can be queried in advance, but allocation may fail for other reasons. virtual bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*) = 0; - virtual void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId, + virtual void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId, uint8_t port, std::optional<ui::Size> physicalSize) = 0; // Attempts to create a new layer on this display @@ -231,11 +232,12 @@ public: // Events handling --------------------------------------------------------- - // Returns stable display ID (and display name on connection of new or previously disconnected - // display), or std::nullopt if hotplug event was ignored. + enum class HotplugEvent { Connected, Disconnected, LinkUnstable }; + + // Returns the stable display ID of the display for which the hotplug event was received, or + // std::nullopt if hotplug event was ignored. // This function is called from SurfaceFlinger. - virtual std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, - hal::Connection) = 0; + virtual std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, HotplugEvent) = 0; // If true we'll update the DeviceProductInfo on subsequent hotplug connected events. // TODO(b/157555476): Remove when the framework has proper support for headless mode @@ -361,7 +363,7 @@ public: bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*) override; // Called from SurfaceFlinger, when the state for a new physical display needs to be recreated. - void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId, + void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId, uint8_t port, std::optional<ui::Size> physicalSize) override; // Attempts to create a new layer on this display @@ -435,9 +437,7 @@ public: // Events handling --------------------------------------------------------- - // Returns PhysicalDisplayId (and display name on connection of new or previously disconnected - // display), or std::nullopt if hotplug event was ignored. - std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, hal::Connection) override; + std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, HotplugEvent) override; bool updatesDeviceProductInfoOnHotplugReconnect() const override; @@ -526,6 +526,7 @@ private: struct DisplayData { std::unique_ptr<HWC2::Display> hwcDisplay; + std::optional<uint8_t> port; // Set on hotplug for physical displays sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires nsecs_t lastPresentTimestamp = 0; @@ -543,7 +544,9 @@ private: std::optional<DisplayIdentificationInfo> onHotplugConnect(hal::HWDisplayId); std::optional<DisplayIdentificationInfo> onHotplugDisconnect(hal::HWDisplayId); - bool shouldIgnoreHotplugConnect(hal::HWDisplayId, bool hasDisplayIdentificationData) const; + std::optional<DisplayIdentificationInfo> onHotplugLinkTrainingFailure(hal::HWDisplayId); + bool shouldIgnoreHotplugConnect(hal::HWDisplayId, uint8_t port, + bool hasDisplayIdentificationData) const; aidl::android::hardware::graphics::composer3::DisplayConfiguration::Dpi getEstimatedDotsPerInchFromSize(uint64_t hwcDisplayId, const HWCDisplayMode& hwcMode) const; @@ -565,6 +568,7 @@ private: void loadHdrConversionCapabilities(); std::unordered_map<HalDisplayId, DisplayData> mDisplayData; + ui::PhysicalDisplaySet<uint8_t> mActivePorts; std::unique_ptr<android::Hwc2::Composer> mComposer; std::unordered_set<aidl::android::hardware::graphics::composer3::Capability> mCapabilities; diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp index ec155392eb..a010353423 100644 --- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp @@ -28,6 +28,7 @@ #include <aidl/android/hardware/graphics/common/DisplayHotplugEvent.h> #include <android/binder_manager.h> #include <android/hardware/graphics/composer/2.1/types.h> +#include <common/FlagManager.h> #include <common/trace.h> #include <composer-command-buffer/2.2/ComposerCommandBuffer.h> #include <hidl/HidlTransportSupport.h> @@ -301,7 +302,9 @@ std::string HidlComposer::dumpDebugInfo() { } void HidlComposer::registerCallback(const sp<IComposerCallback>& callback) { - android::hardware::setMinSchedulerPolicy(callback, SCHED_FIFO, 2); + if (!FlagManager::getInstance().disable_sched_fifo_composer_callback()) { + android::hardware::setMinSchedulerPolicy(callback, SCHED_FIFO, 2); + } auto ret = [&]() { if (mClient_2_4) { @@ -590,6 +593,11 @@ Error HidlComposer::getReleaseFences(Display display, std::vector<Layer>* outLay return Error::NONE; } +Error HidlComposer::getLayerPresentFences(Display, std::vector<Layer>*, std::vector<int>*, + std::vector<int64_t>*) { + return Error::UNSUPPORTED; +} + Error HidlComposer::presentDisplay(Display display, int* outPresentFence) { SFTRACE_NAME("HwcPresentDisplay"); mWriter.selectDisplay(display); diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h index cacdb8ce52..86ca4b1782 100644 --- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h @@ -214,6 +214,10 @@ public: Error getReleaseFences(Display display, std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences) override; + Error getLayerPresentFences(Display display, std::vector<Layer>* outLayers, + std::vector<int>* outFences, + std::vector<int64_t>* outLatenciesNanos) override; + Error presentDisplay(Display display, int* outPresentFence) override; Error setActiveConfig(Display display, Config config) override; diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index 384f7b22c7..56ed11f07a 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -47,7 +47,8 @@ namespace android { -VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, VirtualDisplayId displayId, +VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, + VirtualDisplayIdVariant virtualIdVariant, const sp<IGraphicBufferProducer>& sink, const sp<IGraphicBufferProducer>& bqProducer, const sp<IGraphicBufferConsumer>& bqConsumer, @@ -58,7 +59,7 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, VirtualDisplayId d : ConsumerBase(bqConsumer), #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) mHwc(hwc), - mDisplayId(displayId), + mVirtualIdVariant(virtualIdVariant), mDisplayName(name), mSource{}, mDefaultOutputFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED), @@ -119,7 +120,7 @@ VirtualDisplaySurface::~VirtualDisplaySurface() { } status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) { - if (GpuVirtualDisplayId::tryCast(mDisplayId)) { + if (isBackedByGpu()) { return NO_ERROR; } @@ -133,7 +134,7 @@ status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) { } status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) { - if (GpuVirtualDisplayId::tryCast(mDisplayId)) { + if (isBackedByGpu()) { return NO_ERROR; } @@ -181,7 +182,10 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) { } status_t VirtualDisplaySurface::advanceFrame(float hdrSdrRatio) { - if (GpuVirtualDisplayId::tryCast(mDisplayId)) { + const auto halVirtualDisplayId = ftl::match( + mVirtualIdVariant, [](HalVirtualDisplayId id) { return ftl::Optional(id); }, + [](auto) { return ftl::Optional<HalVirtualDisplayId>(); }); + if (!halVirtualDisplayId) { return NO_ERROR; } @@ -212,11 +216,8 @@ status_t VirtualDisplaySurface::advanceFrame(float hdrSdrRatio) { VDS_LOGV("%s: fb=%d(%p) out=%d(%p)", __func__, mFbProducerSlot, fbBuffer.get(), mOutputProducerSlot, outBuffer.get()); - const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId); - LOG_FATAL_IF(!halDisplayId); - // At this point we know the output buffer acquire fence, - // so update HWC state with it. - mHwc.setOutputBuffer(*halDisplayId, mOutputFence, outBuffer); + // At this point we know the output buffer acquire fence, so update HWC state with it. + mHwc.setOutputBuffer(*halVirtualDisplayId, mOutputFence, outBuffer); status_t result = NO_ERROR; if (fbBuffer != nullptr) { @@ -227,7 +228,7 @@ status_t VirtualDisplaySurface::advanceFrame(float hdrSdrRatio) { hwcBuffer = fbBuffer; // HWC hasn't previously seen this buffer in this slot } // TODO: Correctly propagate the dataspace from GL composition - result = mHwc.setClientTarget(*halDisplayId, mFbProducerSlot, mFbFence, hwcBuffer, + result = mHwc.setClientTarget(*halVirtualDisplayId, mFbProducerSlot, mFbFence, hwcBuffer, ui::Dataspace::UNKNOWN, hdrSdrRatio); } @@ -235,8 +236,8 @@ status_t VirtualDisplaySurface::advanceFrame(float hdrSdrRatio) { } void VirtualDisplaySurface::onFrameCommitted() { - const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId); - if (!halDisplayId) { + const auto halDisplayId = asHalDisplayId(mVirtualIdVariant); + if (!halDisplayId.has_value()) { return; } @@ -250,8 +251,7 @@ void VirtualDisplaySurface::onFrameCommitted() { Mutex::Autolock lock(mMutex); int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot); VDS_LOGV("%s: release scratch sslot=%d", __func__, sslot); - addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], - retireFence); + addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], retireFence); releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot]); } @@ -299,7 +299,7 @@ const sp<Fence>& VirtualDisplaySurface::getClientTargetAcquireFence() const { status_t VirtualDisplaySurface::requestBuffer(int pslot, sp<GraphicBuffer>* outBuf) { - if (GpuVirtualDisplayId::tryCast(mDisplayId)) { + if (isBackedByGpu()) { return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf); } @@ -321,7 +321,7 @@ status_t VirtualDisplaySurface::setAsyncMode(bool async) { status_t VirtualDisplaySurface::dequeueBuffer(Source source, PixelFormat format, uint64_t usage, int* sslot, sp<Fence>* fence) { - LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value()); + LOG_ALWAYS_FATAL_IF(isBackedByGpu()); status_t result = mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight, @@ -373,7 +373,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, uint PixelFormat format, uint64_t usage, uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps) { - if (GpuVirtualDisplayId::tryCast(mDisplayId)) { + if (isBackedByGpu()) { return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, w, h, format, usage, outBufferAge, outTimestamps); } @@ -459,7 +459,7 @@ status_t VirtualDisplaySurface::attachBuffer(int*, const sp<GraphicBuffer>&) { status_t VirtualDisplaySurface::queueBuffer(int pslot, const QueueBufferInput& input, QueueBufferOutput* output) { - if (GpuVirtualDisplayId::tryCast(mDisplayId)) { + if (isBackedByGpu()) { return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output); } @@ -517,7 +517,7 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot, status_t VirtualDisplaySurface::cancelBuffer(int pslot, const sp<Fence>& fence) { - if (GpuVirtualDisplayId::tryCast(mDisplayId)) { + if (isBackedByGpu()) { return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence); } @@ -621,7 +621,10 @@ void VirtualDisplaySurface::resetPerFrameState() { } status_t VirtualDisplaySurface::refreshOutputBuffer() { - LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value()); + const auto halVirtualDisplayId = ftl::match( + mVirtualIdVariant, [](HalVirtualDisplayId id) { return ftl::Optional(id); }, + [](auto) { return ftl::Optional<HalVirtualDisplayId>(); }); + LOG_ALWAYS_FATAL_IF(!halVirtualDisplayId); if (mOutputProducerSlot >= 0) { mSource[SOURCE_SINK]->cancelBuffer( @@ -640,14 +643,16 @@ status_t VirtualDisplaySurface::refreshOutputBuffer() { // until after GPU calls queueBuffer(). So here we just set the buffer // (for use in HWC prepare) but not the fence; we'll call this again with // the proper fence once we have it. - const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId); - LOG_FATAL_IF(!halDisplayId); - result = mHwc.setOutputBuffer(*halDisplayId, Fence::NO_FENCE, + result = mHwc.setOutputBuffer(*halVirtualDisplayId, Fence::NO_FENCE, mProducerBuffers[mOutputProducerSlot]); return result; } +bool VirtualDisplaySurface::isBackedByGpu() const { + return std::holds_alternative<GpuVirtualDisplayId>(mVirtualIdVariant); +} + // This slot mapping function is its own inverse, so two copies are unnecessary. // Both are kept to make the intent clear where the function is called, and for // the (unlikely) chance that we switch to a different mapping function. diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index 90426f729a..cb65c79152 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -75,7 +75,8 @@ class VirtualDisplaySurface : public compositionengine::DisplaySurface, public BnGraphicBufferProducer, private ConsumerBase { public: - VirtualDisplaySurface(HWComposer&, VirtualDisplayId, const sp<IGraphicBufferProducer>& sink, + VirtualDisplaySurface(HWComposer&, VirtualDisplayIdVariant, + const sp<IGraphicBufferProducer>& sink, const sp<IGraphicBufferProducer>& bqProducer, const sp<IGraphicBufferConsumer>& bqConsumer, const std::string& name); @@ -145,6 +146,7 @@ private: void updateQueueBufferOutput(QueueBufferOutput&&); void resetPerFrameState(); status_t refreshOutputBuffer(); + bool isBackedByGpu() const; // Both the sink and scratch buffer pools have their own set of slots // ("source slots", or "sslot"). We have to merge these into the single @@ -159,7 +161,7 @@ private: // Immutable after construction // HWComposer& mHwc; - const VirtualDisplayId mDisplayId; + const VirtualDisplayIdVariant mVirtualIdVariant; const std::string mDisplayName; sp<IGraphicBufferProducer> mSource[2]; // indexed by SOURCE_* uint32_t mDefaultOutputFormat; diff --git a/services/surfaceflinger/DisplayRenderArea.cpp b/services/surfaceflinger/DisplayRenderArea.cpp deleted file mode 100644 index c63c738d34..0000000000 --- a/services/surfaceflinger/DisplayRenderArea.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "DisplayRenderArea.h" -#include "DisplayDevice.h" - -namespace android { - -std::unique_ptr<RenderArea> DisplayRenderArea::create(wp<const DisplayDevice> displayWeak, - const Rect& sourceCrop, ui::Size reqSize, - ui::Dataspace reqDataSpace, - ftl::Flags<Options> options) { - if (auto display = displayWeak.promote()) { - // Using new to access a private constructor. - return std::unique_ptr<DisplayRenderArea>(new DisplayRenderArea(std::move(display), - sourceCrop, reqSize, - reqDataSpace, options)); - } - return nullptr; -} - -DisplayRenderArea::DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, - ui::Size reqSize, ui::Dataspace reqDataSpace, - ftl::Flags<Options> options) - : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, options), - mDisplay(std::move(display)), - mSourceCrop(sourceCrop) {} - -const ui::Transform& DisplayRenderArea::getTransform() const { - return mTransform; -} - -bool DisplayRenderArea::isSecure() const { - return mOptions.test(Options::CAPTURE_SECURE_LAYERS) && mDisplay->isSecure(); -} - -sp<const DisplayDevice> DisplayRenderArea::getDisplayDevice() const { - return mDisplay; -} - -Rect DisplayRenderArea::getSourceCrop() const { - // use the projected display viewport by default. - if (mSourceCrop.isEmpty()) { - return mDisplay->getLayerStackSpaceRect(); - } - return mSourceCrop; -} - -} // namespace android diff --git a/services/surfaceflinger/DisplayRenderArea.h b/services/surfaceflinger/DisplayRenderArea.h deleted file mode 100644 index 677d01975a..0000000000 --- a/services/surfaceflinger/DisplayRenderArea.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <ui/GraphicTypes.h> -#include <ui/Transform.h> - -#include "RenderArea.h" - -namespace android { - -class DisplayDevice; - -class DisplayRenderArea : public RenderArea { -public: - static std::unique_ptr<RenderArea> create(wp<const DisplayDevice>, const Rect& sourceCrop, - ui::Size reqSize, ui::Dataspace, - ftl::Flags<Options> options); - - const ui::Transform& getTransform() const override; - bool isSecure() const override; - sp<const DisplayDevice> getDisplayDevice() const override; - Rect getSourceCrop() const override; - -private: - DisplayRenderArea(sp<const DisplayDevice>, const Rect& sourceCrop, ui::Size reqSize, - ui::Dataspace, ftl::Flags<Options> options); - - const sp<const DisplayDevice> mDisplay; - const Rect mSourceCrop; - const ui::Transform mTransform; -}; - -} // namespace android diff --git a/services/surfaceflinger/FrameTimeline/Android.bp b/services/surfaceflinger/FrameTimeline/Android.bp deleted file mode 100644 index 8e28cc3c17..0000000000 --- a/services/surfaceflinger/FrameTimeline/Android.bp +++ /dev/null @@ -1,35 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_native_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_native_license"], - default_team: "trendy_team_android_core_graphics_stack", -} - -cc_library_static { - name: "libframetimeline", - defaults: ["surfaceflinger_defaults"], - srcs: [ - "FrameTimeline.cpp", - ], - header_libs: [ - "libscheduler_headers", - ], - shared_libs: [ - "android.hardware.graphics.composer@2.4", - "libbase", - "libcutils", - "liblog", - "libgui", - "libtimestats", - "libui", - "libutils", - ], - static_libs: [ - "libperfetto_client_experimental", - "libsurfaceflinger_common", - ], - export_include_dirs: ["."], -} diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp index 86d7388f5b..008b0571c3 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp @@ -611,7 +611,11 @@ void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& r mFrameReadyMetadata = FrameReadyMetadata::OnTimeFinish; } - if (std::abs(presentDelta) > mJankClassificationThresholds.presentThreshold) { + const nsecs_t presentThreshold = + FlagManager::getInstance().increase_missed_frame_jank_threshold() + ? mJankClassificationThresholds.presentThresholdExtended + : mJankClassificationThresholds.presentThresholdLegacy; + if (std::abs(presentDelta) > presentThreshold) { mFramePresentMetadata = presentDelta > 0 ? FramePresentMetadata::LatePresent : FramePresentMetadata::EarlyPresent; // Jank that is missing by less than the render rate period is classified as partial jank, @@ -629,9 +633,8 @@ void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& r } else if (mFramePresentMetadata == FramePresentMetadata::EarlyPresent) { if (mFrameReadyMetadata == FrameReadyMetadata::OnTimeFinish) { // Finish on time, Present early - if (deltaToVsync < mJankClassificationThresholds.presentThreshold || - deltaToVsync >= refreshRate.getPeriodNsecs() - - mJankClassificationThresholds.presentThreshold) { + if (deltaToVsync < presentThreshold || + deltaToVsync >= refreshRate.getPeriodNsecs() - presentThreshold) { // Delta factor of vsync mJankType = JankType::SurfaceFlingerScheduling; } else { @@ -651,7 +654,7 @@ void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& r // We try to do this by moving the deadline. Since the queue could be stuffed by more // than one buffer, we take the last latch time as reference and give one vsync // worth of time for the frame to be ready. - nsecs_t adjustedDeadline = mLastLatchTime + refreshRate.getPeriodNsecs(); + nsecs_t adjustedDeadline = mLastLatchTime + displayFrameRenderRate.getPeriodNsecs(); if (adjustedDeadline > mActuals.endTime) { mFrameReadyMetadata = FrameReadyMetadata::OnTimeFinish; } else { @@ -667,9 +670,8 @@ void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& r if (!(mJankType & JankType::BufferStuffing)) { // In a stuffed state, if the app finishes on time and there is no display frame // jank, only buffer stuffing is the root cause of the jank. - if (deltaToVsync < mJankClassificationThresholds.presentThreshold || - deltaToVsync >= refreshRate.getPeriodNsecs() - - mJankClassificationThresholds.presentThreshold) { + if (deltaToVsync < presentThreshold || + deltaToVsync >= refreshRate.getPeriodNsecs() - presentThreshold) { // Delta factor of vsync mJankType |= JankType::SurfaceFlingerScheduling; } else { @@ -1091,7 +1093,11 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& ? std::abs(presentDelta) % mRefreshRate.getPeriodNsecs() : 0; - if (std::abs(presentDelta) > mJankClassificationThresholds.presentThreshold) { + nsecs_t presentThreshold = FlagManager::getInstance().increase_missed_frame_jank_threshold() + ? mJankClassificationThresholds.presentThresholdExtended + : mJankClassificationThresholds.presentThresholdLegacy; + + if (std::abs(presentDelta) > presentThreshold) { mFramePresentMetadata = presentDelta > 0 ? FramePresentMetadata::LatePresent : FramePresentMetadata::EarlyPresent; // Jank that is missing by less than the render rate period is classified as partial jank, @@ -1122,9 +1128,8 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& if (mFramePresentMetadata == FramePresentMetadata::EarlyPresent) { if (mFrameReadyMetadata == FrameReadyMetadata::OnTimeFinish) { // Finish on time, Present early - if (deltaToVsync < mJankClassificationThresholds.presentThreshold || - deltaToVsync >= (mRefreshRate.getPeriodNsecs() - - mJankClassificationThresholds.presentThreshold)) { + if (deltaToVsync < presentThreshold || + deltaToVsync >= (mRefreshRate.getPeriodNsecs() - presentThreshold)) { // Delta is a factor of vsync if its within the presentTheshold on either side // of the vsyncPeriod. Example: 0-2ms and 9-11ms are both within the threshold // of the vsyncPeriod if the threshold was 2ms and the vsyncPeriod was 11ms. @@ -1142,7 +1147,7 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& } } else if (mFramePresentMetadata == FramePresentMetadata::LatePresent) { if (std::abs(mSurfaceFlingerPredictions.presentTime - previousPresentTime) <= - mJankClassificationThresholds.presentThreshold || + presentThreshold || previousPresentTime > mSurfaceFlingerPredictions.presentTime) { // The previous frame was either presented in the current frame's expected vsync or // it was presented even later than the current frame's expected vsync. @@ -1151,9 +1156,8 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& if (mFrameReadyMetadata == FrameReadyMetadata::OnTimeFinish && !(mJankType & JankType::SurfaceFlingerStuffing)) { // Finish on time, Present late - if (deltaToVsync < mJankClassificationThresholds.presentThreshold || - deltaToVsync >= (mRefreshRate.getPeriodNsecs() - - mJankClassificationThresholds.presentThreshold)) { + if (deltaToVsync < presentThreshold || + deltaToVsync >= (mRefreshRate.getPeriodNsecs() - presentThreshold)) { // Delta is a factor of vsync if its within the presentTheshold on either side // of the vsyncPeriod. Example: 0-2ms and 9-11ms are both within the threshold // of the vsyncPeriod if the threshold was 2ms and the vsyncPeriod was 11ms. @@ -1165,8 +1169,7 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& } else if (mFrameReadyMetadata == FrameReadyMetadata::LateFinish) { if (!(mJankType & JankType::SurfaceFlingerStuffing) || mSurfaceFlingerActuals.presentTime - previousPresentTime > - mRefreshRate.getPeriodNsecs() + - mJankClassificationThresholds.presentThreshold) { + mRefreshRate.getPeriodNsecs() + presentThreshold) { // Classify CPU vs GPU if SF wasn't stuffed or if SF was stuffed but this frame // was presented more than a vsync late. if (mGpuFence != FenceTime::NO_FENCE) { diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h index a47bd573de..9fedb57aca 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h @@ -107,7 +107,10 @@ struct TimelineItem { struct JankClassificationThresholds { // The various thresholds for App and SF. If the actual timestamp falls within the threshold // compared to prediction, we treat it as on time. - nsecs_t presentThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count(); + nsecs_t presentThresholdLegacy = + std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count(); + nsecs_t presentThresholdExtended = + std::chrono::duration_cast<std::chrono::nanoseconds>(4ms).count(); nsecs_t deadlineThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(0ms).count(); nsecs_t startThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count(); }; diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.h b/services/surfaceflinger/FrontEnd/LayerHierarchy.h index 47d0041a8b..4fdbae1831 100644 --- a/services/surfaceflinger/FrontEnd/LayerHierarchy.h +++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.h @@ -102,6 +102,8 @@ public: // Returns true if the node is a clone. bool isClone() const { return !mirrorRootIds.empty(); } + TraversalPath getClonedFrom() const { return {.id = id, .variant = variant}; } + bool operator==(const TraversalPath& other) const { return id == other.id && mirrorRootIds == other.mirrorRootIds; } diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp index 367132c113..964a9703b3 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp @@ -18,12 +18,17 @@ #undef LOG_TAG #define LOG_TAG "SurfaceFlinger" -#include "LayerSnapshot.h" +#include <PowerAdvisor/Workload.h> +#include <aidl/android/hardware/graphics/composer3/Composition.h> +#include <gui/LayerState.h> + #include "Layer.h" +#include "LayerSnapshot.h" namespace android::surfaceflinger::frontend { using namespace ftl::flag_operators; +using namespace aidl::android::hardware::graphics::composer3; namespace { @@ -36,7 +41,7 @@ void updateSurfaceDamage(const RequestedLayerState& requested, bool hasReadyFram if (forceFullDamage) { outSurfaceDamageRegion = Region::INVALID_REGION; } else { - outSurfaceDamageRegion = requested.surfaceDamageRegion; + outSurfaceDamageRegion = requested.getSurfaceDamageRegion(); } } @@ -300,7 +305,11 @@ std::ostream& operator<<(std::ostream& out, const LayerSnapshot& obj) { out << rootId << ","; } } - out << "] " << obj.name << "\n " << (obj.isVisible ? "visible" : "invisible") + out << "] "; + if (obj.isSecure) { + out << "(Secure) "; + } + out << obj.name << "\n " << (obj.isVisible ? "visible" : "invisible") << " reason=" << obj.getIsVisibleReason(); if (!obj.geomLayerBounds.isEmpty()) { @@ -367,7 +376,7 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate updateSurfaceDamage(requested, requested.hasReadyFrame(), forceFullDamage, surfaceDamage); if (forceUpdate || requested.what & layer_state_t::eTransparentRegionChanged) { - transparentRegionHint = requested.transparentRegion; + transparentRegionHint = requested.getTransparentRegion(); } if (forceUpdate || requested.what & layer_state_t::eFlagsChanged) { layerOpaqueFlagSet = @@ -401,6 +410,7 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate if (forceUpdate || requested.what & layer_state_t::eShadowRadiusChanged) { shadowSettings.length = requested.shadowRadius; } + if (forceUpdate || requested.what & layer_state_t::eFrameRateSelectionPriority) { frameRateSelectionPriority = requested.frameRateSelectionPriority; } @@ -438,15 +448,7 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate } if (forceUpdate || requested.what & layer_state_t::eInputInfoChanged) { - if (requested.windowInfoHandle) { - inputInfo = *requested.windowInfoHandle->getInfo(); - } else { - inputInfo = {}; - // b/271132344 revisit this and see if we can always use the layers uid/pid - inputInfo.name = requested.name; - inputInfo.ownerUid = requested.ownerUid; - inputInfo.ownerPid = requested.ownerPid; - } + inputInfo = requested.getWindowInfo(); inputInfo.id = static_cast<int32_t>(uniqueSequence); touchCropId = requested.touchCropId; } @@ -528,4 +530,50 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate } } +char LayerSnapshot::classifyCompositionForDebug( + const compositionengine::LayerFE::HwcLayerDebugState& hwcState) const { + if (!isVisible) { + return '.'; + } + + switch (hwcState.lastCompositionType) { + case Composition::INVALID: + return 'i'; + case Composition::SOLID_COLOR: + return 'c'; + case Composition::CURSOR: + return 'u'; + case Composition::SIDEBAND: + return 'd'; + case Composition::DISPLAY_DECORATION: + return 'a'; + case Composition::REFRESH_RATE_INDICATOR: + return 'r'; + case Composition::CLIENT: + case Composition::DEVICE: + break; + } + + char code = '.'; // Default to invisible + if (hasBlur()) { + code = 'l'; // Blur + } else if (hasProtectedContent) { + code = 'p'; // Protected content + } else if (roundedCorner.hasRoundedCorners()) { + code = 'r'; // Rounded corners + } else if (drawShadows()) { + code = 's'; // Shadow + } else if (fillsColor()) { + code = 'c'; // Solid color + } else if (hasBufferOrSidebandStream()) { + code = 'b'; + } + + if (hwcState.lastCompositionType == Composition::CLIENT) { + return static_cast<char>(std::toupper(code)); + } else { + return code; + } +} + } // namespace android::surfaceflinger::frontend diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h index b8df3ed748..69120bdcff 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h +++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h @@ -16,6 +16,7 @@ #pragma once +#include <PowerAdvisor/Workload.h> #include <compositionengine/LayerFECompositionState.h> #include <renderengine/LayerSettings.h> #include "DisplayHardware/ComposerHal.h" @@ -23,21 +24,29 @@ #include "RequestedLayerState.h" #include "Scheduler/LayerInfo.h" #include "android-base/stringprintf.h" +#include "compositionengine/LayerFE.h" namespace android::surfaceflinger::frontend { struct RoundedCornerState { RoundedCornerState() = default; - RoundedCornerState(const FloatRect& cropRect, const vec2& radius) - : cropRect(cropRect), radius(radius) {} // Rounded rectangle in local layer coordinate space. FloatRect cropRect = FloatRect(); - // Radius of the rounded rectangle. + // Radius of the rounded rectangle for composition vec2 radius; + // Requested radius of the rounded rectangle + vec2 requestedRadius; + // Radius drawn by client for the rounded rectangle + vec2 clientDrawnRadius; + bool hasClientDrawnRadius() const { + return clientDrawnRadius.x > 0.0f && clientDrawnRadius.y > 0.0f; + } + bool hasRequestedRadius() const { return requestedRadius.x > 0.0f && requestedRadius.y > 0.0f; } bool hasRoundedCorners() const { return radius.x > 0.0f && radius.y > 0.0f; } bool operator==(RoundedCornerState const& rhs) const { - return cropRect == rhs.cropRect && radius == rhs.radius; + return cropRect == rhs.cropRect && radius == rhs.radius && + clientDrawnRadius == rhs.clientDrawnRadius; } }; @@ -152,6 +161,10 @@ struct LayerSnapshot : public compositionengine::LayerFECompositionState { friend std::ostream& operator<<(std::ostream& os, const LayerSnapshot& obj); void merge(const RequestedLayerState& requested, bool forceUpdate, bool displayChanges, bool forceFullDamage, uint32_t displayRotationFlags); + // Returns a char summarizing the composition request + // This function tries to maintain parity with planner::Plan chars. + char classifyCompositionForDebug( + const compositionengine::LayerFE::HwcLayerDebugState& hwcState) const; }; } // namespace android::surfaceflinger::frontend diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp index 022588deef..28a6031c97 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp @@ -16,6 +16,8 @@ // #define LOG_NDEBUG 0 #define ATRACE_TAG ATRACE_TAG_GRAPHICS +#include "FrontEnd/LayerSnapshot.h" +#include "ui/Transform.h" #undef LOG_TAG #define LOG_TAG "SurfaceFlinger" @@ -25,6 +27,7 @@ #include <common/FlagManager.h> #include <common/trace.h> #include <ftl/small_map.h> +#include <math/vec2.h> #include <ui/DisplayMap.h> #include <ui/FloatRect.h> @@ -261,28 +264,21 @@ void updateVisibility(LayerSnapshot& snapshot, bool visible) { } snapshot.isVisible = visible; - if (FlagManager::getInstance().skip_invisible_windows_in_input()) { - const bool visibleForInput = - snapshot.isVisible || (snapshot.hasInputInfo() && !snapshot.isHiddenByPolicy()); - snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, - !visibleForInput); - } else { - // TODO(b/238781169) we are ignoring this compat for now, since we will have - // to remove any optimization based on visibility. - - // For compatibility reasons we let layers which can receive input - // receive input before they have actually submitted a buffer. Because - // of this we use canReceiveInput instead of isVisible to check the - // policy-visibility, ignoring the buffer state. However for layers with - // hasInputInfo()==false we can use the real visibility state. - // We are just using these layers for occlusion detection in - // InputDispatcher, and obviously if they aren't visible they can't occlude - // anything. - const bool visibleForInput = - snapshot.hasInputInfo() ? snapshot.canReceiveInput() : snapshot.isVisible; - snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, - !visibleForInput); - } + // TODO(b/238781169) we are ignoring this compat for now, since we will have + // to remove any optimization based on visibility. + + // For compatibility reasons we let layers which can receive input + // receive input before they have actually submitted a buffer. Because + // of this we use canReceiveInput instead of isVisible to check the + // policy-visibility, ignoring the buffer state. However for layers with + // hasInputInfo()==false we can use the real visibility state. + // We are just using these layers for occlusion detection in + // InputDispatcher, and obviously if they aren't visible they can't occlude + // anything. + const bool visibleForInput = + snapshot.hasInputInfo() ? snapshot.canReceiveInput() : snapshot.isVisible; + snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visibleForInput); + LLOGV(snapshot.sequence, "updating visibility %s %s", visible ? "true" : "false", snapshot.getDebugString().c_str()); } @@ -932,7 +928,8 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a if (forceUpdate || snapshot.clientChanges & layer_state_t::eCornerRadiusChanged || snapshot.changes.any(RequestedLayerState::Changes::Geometry | - RequestedLayerState::Changes::BufferUsageFlags)) { + RequestedLayerState::Changes::BufferUsageFlags) || + snapshot.clientChanges & layer_state_t::eClientDrawnCornerRadiusChanged) { updateRoundedCorner(snapshot, requested, parentSnapshot, args); } @@ -972,19 +969,27 @@ void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot, } snapshot.roundedCorner = RoundedCornerState(); RoundedCornerState parentRoundedCorner; - if (parentSnapshot.roundedCorner.hasRoundedCorners()) { + if (parentSnapshot.roundedCorner.hasRequestedRadius()) { parentRoundedCorner = parentSnapshot.roundedCorner; ui::Transform t = snapshot.localTransform.inverse(); parentRoundedCorner.cropRect = t.transform(parentRoundedCorner.cropRect); parentRoundedCorner.radius.x *= t.getScaleX(); parentRoundedCorner.radius.y *= t.getScaleY(); + parentRoundedCorner.requestedRadius.x *= t.getScaleX(); + parentRoundedCorner.requestedRadius.y *= t.getScaleY(); } FloatRect layerCropRect = snapshot.croppedBufferSize; - const vec2 radius(requested.cornerRadius, requested.cornerRadius); - RoundedCornerState layerSettings(layerCropRect, radius); - const bool layerSettingsValid = layerSettings.hasRoundedCorners() && !layerCropRect.isEmpty(); - const bool parentRoundedCornerValid = parentRoundedCorner.hasRoundedCorners(); + const vec2 requestedRadius(requested.cornerRadius, requested.cornerRadius); + const vec2 clientDrawnRadius(requested.clientDrawnCornerRadius, + requested.clientDrawnCornerRadius); + RoundedCornerState layerSettings; + layerSettings.cropRect = layerCropRect; + layerSettings.requestedRadius = requestedRadius; + layerSettings.clientDrawnRadius = clientDrawnRadius; + + const bool layerSettingsValid = layerSettings.hasRequestedRadius() && !layerCropRect.isEmpty(); + const bool parentRoundedCornerValid = parentRoundedCorner.hasRequestedRadius(); if (layerSettingsValid && parentRoundedCornerValid) { // If the parent and the layer have rounded corner settings, use the parent settings if // the parent crop is entirely inside the layer crop. This has limitations and cause @@ -1002,6 +1007,14 @@ void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot, } else if (parentRoundedCornerValid) { snapshot.roundedCorner = parentRoundedCorner; } + + if (snapshot.roundedCorner.requestedRadius.x == requested.clientDrawnCornerRadius) { + // If the client drawn radius matches the requested radius, then surfaceflinger + // does not need to draw rounded corners for this layer + snapshot.roundedCorner.radius = vec2(0.f, 0.f); + } else { + snapshot.roundedCorner.radius = snapshot.roundedCorner.requestedRadius; + } } /** @@ -1077,7 +1090,7 @@ void LayerSnapshotBuilder::updateLayerBounds(LayerSnapshot& snapshot, snapshot.transformedBounds = snapshot.geomLayerTransform.transform(snapshot.geomLayerBounds); const Rect geomLayerBoundsWithoutTransparentRegion = RequestedLayerState::reduce(Rect(snapshot.geomLayerBounds), - requested.transparentRegion); + requested.getTransparentRegion()); snapshot.transformedBoundsWithoutTransparentRegion = snapshot.geomLayerTransform.transform(geomLayerBoundsWithoutTransparentRegion); snapshot.parentTransform = parentSnapshot.geomLayerTransform; @@ -1085,7 +1098,7 @@ void LayerSnapshotBuilder::updateLayerBounds(LayerSnapshot& snapshot, if (requested.potentialCursor) { // Subtract the transparent region and snap to the bounds const Rect bounds = RequestedLayerState::reduce(Rect(snapshot.croppedBufferSize), - requested.transparentRegion); + requested.getTransparentRegion()); snapshot.cursorFrame = snapshot.geomLayerTransform.transform(bounds); } } @@ -1119,22 +1132,14 @@ void LayerSnapshotBuilder::updateInput(LayerSnapshot& snapshot, const Args& args) { using InputConfig = gui::WindowInfo::InputConfig; - if (requested.windowInfoHandle) { - snapshot.inputInfo = *requested.windowInfoHandle->getInfo(); - } else { - snapshot.inputInfo = {}; - // b/271132344 revisit this and see if we can always use the layers uid/pid - snapshot.inputInfo.name = requested.name; - snapshot.inputInfo.ownerUid = gui::Uid{requested.ownerUid}; - snapshot.inputInfo.ownerPid = gui::Pid{requested.ownerPid}; - } + snapshot.inputInfo = requested.getWindowInfo(); snapshot.touchCropId = requested.touchCropId; snapshot.inputInfo.id = static_cast<int32_t>(snapshot.uniqueSequence); snapshot.inputInfo.displayId = ui::LogicalDisplayId{static_cast<int32_t>(snapshot.outputFilter.layerStack.id)}; snapshot.inputInfo.touchOcclusionMode = requested.hasInputInfo() - ? requested.windowInfoHandle->getInfo()->touchOcclusionMode + ? requested.getWindowInfo().touchOcclusionMode : parentSnapshot.inputInfo.touchOcclusionMode; snapshot.inputInfo.canOccludePresentation = parentSnapshot.inputInfo.canOccludePresentation || (requested.flags & layer_state_t::eCanOccludePresentation); @@ -1165,7 +1170,7 @@ void LayerSnapshotBuilder::updateInput(LayerSnapshot& snapshot, auto displayInfo = displayInfoOpt.value_or(sDefaultInfo); if (!requested.hasInputInfo()) { - snapshot.inputInfo.inputConfig = InputConfig::NO_INPUT_CHANNEL; + snapshot.inputInfo.inputConfig |= InputConfig::NO_INPUT_CHANNEL; } fillInputFrameInfo(snapshot.inputInfo, displayInfo.transform, snapshot); @@ -1205,13 +1210,27 @@ void LayerSnapshotBuilder::updateInput(LayerSnapshot& snapshot, snapshot.inputInfo.contentSize = {snapshot.croppedBufferSize.getHeight(), snapshot.croppedBufferSize.getWidth()}; - // If the layer is a clone, we need to crop the input region to cloned root to prevent - // touches from going outside the cloned area. + snapshot.inputInfo.cloneLayerStackTransform.reset(); + if (path.isClone()) { snapshot.inputInfo.inputConfig |= InputConfig::CLONE; // Cloned layers shouldn't handle watch outside since their z order is not determined by // WM or the client. snapshot.inputInfo.inputConfig.clear(InputConfig::WATCH_OUTSIDE_TOUCH); + + // Compute the transform that maps the clone's display to the layer stack space of the + // cloned window. + const LayerSnapshot* clonedSnapshot = getSnapshot(path.getClonedFrom()); + if (clonedSnapshot != nullptr) { + const auto& [clonedInputBounds, s] = + getInputBounds(*clonedSnapshot, /*fillParentBounds=*/false); + ui::Transform inputToLayer; + inputToLayer.set(clonedInputBounds.left, clonedInputBounds.top); + const ui::Transform& layerToLayerStack = getInputTransform(*clonedSnapshot); + const auto& displayToInput = snapshot.inputInfo.transform; + snapshot.inputInfo.cloneLayerStackTransform = + layerToLayerStack * inputToLayer * displayToInput; + } } } diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp index ee9302b937..621fd6c00e 100644 --- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp +++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp @@ -63,8 +63,11 @@ RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args) metadata.merge(args.metadata); changes |= RequestedLayerState::Changes::Metadata; handleAlive = true; - // TODO: b/305254099 remove once we don't pass invisible windows to input - windowInfoHandle = nullptr; + // b/271132344 revisit this and see if we can always use the layers uid/pid + auto* windowInfo = editWindowInfo(); + windowInfo->name = name; + windowInfo->ownerPid = ownerPid; + windowInfo->ownerUid = ownerUid; if (parentId != UNASSIGNED_LAYER_ID) { canBeRoot = false; } @@ -105,8 +108,9 @@ RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args) currentHdrSdrRatio = 1.f; dataspaceRequested = false; hdrMetadata.validTypes = 0; - surfaceDamageRegion = Region::INVALID_REGION; + mNotDefCmpState.surfaceDamageRegion = Region::INVALID_REGION; cornerRadius = 0.0f; + clientDrawnCornerRadius = 0.0f; backgroundBlurRadius = 0; api = -1; hasColorTransform = false; @@ -146,6 +150,7 @@ RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args) } void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerState) { + bool transformWasValid = transformIsValid; const uint32_t oldFlags = flags; const half oldAlpha = color.a; const bool hadBuffer = externalTexture != nullptr; @@ -277,7 +282,7 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta if (clientState.what & layer_state_t::eReparent) { changes |= RequestedLayerState::Changes::Parent; parentId = resolvedComposerState.parentId; - parentSurfaceControlForChild = nullptr; + mNotDefCmpState.parentSurfaceControlForChild = nullptr; // Once a layer has be reparented, it cannot be placed at the root. It sounds odd // but thats the existing logic and until we make this behavior more explicit, we need // to maintain this logic. @@ -287,7 +292,7 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta changes |= RequestedLayerState::Changes::RelativeParent; relativeParentId = resolvedComposerState.relativeParentId; isRelativeOf = true; - relativeLayerSurfaceControl = nullptr; + mNotDefCmpState.relativeLayerSurfaceControl = nullptr; } if ((clientState.what & layer_state_t::eLayerChanged || (clientState.what & layer_state_t::eReparent && parentId == UNASSIGNED_LAYER_ID)) && @@ -303,7 +308,7 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta } if (clientState.what & layer_state_t::eInputInfoChanged) { touchCropId = resolvedComposerState.touchCropId; - windowInfoHandle->editInfo()->touchableRegionCropHandle.clear(); + editWindowInfo()->touchableRegionCropHandle.clear(); } if (clientState.what & layer_state_t::eStretchChanged) { stretchEffect.sanitize(); @@ -348,6 +353,19 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta requestedFrameRate.category = category; changes |= RequestedLayerState::Changes::FrameRate; } + + if (clientState.what & layer_state_t::eClientDrawnCornerRadiusChanged) { + clientDrawnCornerRadius = clientState.clientDrawnCornerRadius; + changes |= RequestedLayerState::Changes::Geometry; + } + + // We can't just check requestedTransform here because LayerSnapshotBuilder uses + // getTransform which reads destinationFrame or buffer dimensions. + // Display rotation does not affect validity so just use ROT_0. + transformIsValid = LayerSnapshot::isTransformValid(getTransform(ui::Transform::ROT_0)); + if (!transformWasValid && transformIsValid) { + changes |= RequestedLayerState::Changes::Visibility; + } } ui::Size RequestedLayerState::getUnrotatedBufferSize(uint32_t displayRotationFlags) const { @@ -548,12 +566,9 @@ bool RequestedLayerState::hasValidRelativeParent() const { } bool RequestedLayerState::hasInputInfo() const { - if (!windowInfoHandle) { - return false; - } - const auto windowInfo = windowInfoHandle->getInfo(); - return windowInfo->token != nullptr || - windowInfo->inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL); + const auto& windowInfo = getWindowInfo(); + return windowInfo.token != nullptr || + windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL); } bool RequestedLayerState::needsInputInfo() const { @@ -561,17 +576,22 @@ bool RequestedLayerState::needsInputInfo() const { return false; } - if ((sidebandStream != nullptr) || (externalTexture != nullptr)) { + if (hasBufferOrSidebandStream() || fillsColor()) { return true; } - if (!windowInfoHandle) { - return false; - } + const auto& windowInfo = getWindowInfo(); + return windowInfo.token != nullptr || + windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL); +} + +bool RequestedLayerState::hasBufferOrSidebandStream() const { + return ((sidebandStream != nullptr) || (externalTexture != nullptr)); +} - const auto windowInfo = windowInfoHandle->getInfo(); - return windowInfo->token != nullptr || - windowInfo->inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL); +bool RequestedLayerState::fillsColor() const { + return !hasBufferOrSidebandStream() && color.r >= 0.0_hf && color.g >= 0.0_hf && + color.b >= 0.0_hf; } bool RequestedLayerState::hasBlur() const { @@ -624,6 +644,7 @@ bool RequestedLayerState::isSimpleBufferUpdate(const layer_state_t& s) const { const uint64_t deniedChanges = layer_state_t::ePositionChanged | layer_state_t::eAlphaChanged | layer_state_t::eColorTransformChanged | layer_state_t::eBackgroundColorChanged | layer_state_t::eMatrixChanged | layer_state_t::eCornerRadiusChanged | + layer_state_t::eClientDrawnCornerRadiusChanged | layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBufferTransformChanged | layer_state_t::eTransformToDisplayInverseChanged | layer_state_t::eCropChanged | layer_state_t::eDataspaceChanged | layer_state_t::eHdrMetadataChanged | diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.h b/services/surfaceflinger/FrontEnd/RequestedLayerState.h index dd861a74f4..b8310beab5 100644 --- a/services/surfaceflinger/FrontEnd/RequestedLayerState.h +++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.h @@ -88,6 +88,8 @@ struct RequestedLayerState : layer_state_t { bool hasValidRelativeParent() const; bool hasInputInfo() const; bool needsInputInfo() const; + bool hasBufferOrSidebandStream() const; + bool fillsColor() const; bool hasBlur() const; bool hasFrameUpdate() const; bool hasReadyFrame() const; @@ -113,6 +115,7 @@ struct RequestedLayerState : layer_state_t { const gui::Pid ownerPid; bool dataspaceRequested; bool hasColorTransform; + bool transformIsValid = true; bool premultipliedAlpha{true}; // This layer can be a cursor on some displays. bool potentialCursor{false}; diff --git a/services/surfaceflinger/HdrLayerInfoReporter.h b/services/surfaceflinger/HdrLayerInfoReporter.h index 614f33fbce..758b111e41 100644 --- a/services/surfaceflinger/HdrLayerInfoReporter.h +++ b/services/surfaceflinger/HdrLayerInfoReporter.h @@ -19,11 +19,11 @@ #include <android-base/thread_annotations.h> #include <android/gui/IHdrLayerInfoListener.h> #include <binder/IBinder.h> +#include <ui/RingBuffer.h> #include <utils/Timers.h> #include <unordered_map> -#include "Utils/RingBuffer.h" #include "WpHash.h" namespace android { @@ -102,7 +102,7 @@ private: EventHistoryEntry(const HdrLayerInfo& info) : info(info) { timestamp = systemTime(); } }; - utils::RingBuffer<EventHistoryEntry, 32> mHdrInfoHistory; + ui::RingBuffer<EventHistoryEntry, 32> mHdrInfoHistory; }; } // namespace android
\ No newline at end of file diff --git a/services/surfaceflinger/Jank/JankTracker.cpp b/services/surfaceflinger/Jank/JankTracker.cpp index 8e0e084cd2..5e6267dae4 100644 --- a/services/surfaceflinger/Jank/JankTracker.cpp +++ b/services/surfaceflinger/Jank/JankTracker.cpp @@ -88,7 +88,8 @@ void JankTracker::onJankData(int32_t layerId, gui::JankData data) { } void JankTracker::addJankListenerLocked(int32_t layerId, sp<IBinder> listener) { - for (auto it = mJankListeners.find(layerId); it != mJankListeners.end(); it++) { + auto range = mJankListeners.equal_range(layerId); + for (auto it = range.first; it != range.second; it++) { if (it->second.mListener == listener) { // Undo the duplicate increment in addJankListener. sListenerCount--; @@ -106,7 +107,8 @@ void JankTracker::doFlushJankData(int32_t layerId) { std::vector<sp<IBinder>> toSend; mLock.lock(); - for (auto it = mJankListeners.find(layerId); it != mJankListeners.end();) { + auto range = mJankListeners.equal_range(layerId); + for (auto it = range.first; it != range.second;) { if (!jankData.empty()) { toSend.emplace_back(it->second.mListener); } @@ -133,7 +135,8 @@ void JankTracker::doFlushJankData(int32_t layerId) { void JankTracker::markJankListenerForRemovalLocked(int32_t layerId, sp<IBinder> listener, int64_t afterVysnc) { - for (auto it = mJankListeners.find(layerId); it != mJankListeners.end(); it++) { + auto range = mJankListeners.equal_range(layerId); + for (auto it = range.first; it != range.second; it++) { if (it->second.mListener == listener) { it->second.mRemoveAfter = std::max(static_cast<int64_t>(0), afterVysnc); return; @@ -156,7 +159,8 @@ int64_t JankTracker::transferAvailableJankData(int32_t layerId, void JankTracker::dropJankListener(int32_t layerId, sp<IBinder> listener) { const std::lock_guard<std::mutex> _l(mLock); - for (auto it = mJankListeners.find(layerId); it != mJankListeners.end(); it++) { + auto range = mJankListeners.equal_range(layerId); + for (auto it = range.first; it != range.second; it++) { if (it->second.mListener == listener) { mJankListeners.erase(it); sListenerCount--; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 195461f47e..3a884d6a0b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -64,7 +64,7 @@ #include "DisplayDevice.h" #include "DisplayHardware/HWComposer.h" -#include "FrameTimeline.h" +#include "FrameTimeline/FrameTimeline.h" #include "FrameTracer/FrameTracer.h" #include "FrontEnd/LayerCreationArgs.h" #include "FrontEnd/LayerHandle.h" @@ -362,7 +362,7 @@ aidl::android::hardware::graphics::composer3::Composition Layer::getCompositionT // transaction // ---------------------------------------------------------------------------- -void Layer::commitTransaction() { +void Layer::commitTransaction() REQUIRES(mFlinger->mStateLock) { // Set the present state for all bufferlessSurfaceFramesTX to Presented. The // bufferSurfaceFrameTX will be presented in latchBuffer. for (auto& [token, surfaceFrame] : mDrawingState.bufferlessSurfaceFramesTX) { @@ -394,7 +394,8 @@ bool Layer::isLayerFocusedBasedOnPriority(int32_t priority) { }; void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, - nsecs_t postTime, gui::GameMode gameMode) { + nsecs_t postTime, gui::GameMode gameMode) + REQUIRES(mFlinger->mStateLock) { mDrawingState.postTime = postTime; // Check if one of the bufferlessSurfaceFramesTX contains the same vsyncId. This can happen if @@ -458,7 +459,7 @@ void Layer::addSurfaceFrameDroppedForBuffer( void Layer::addSurfaceFramePresentedForBuffer( std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame, nsecs_t acquireFenceTime, - nsecs_t currentLatchTime) { + nsecs_t currentLatchTime) REQUIRES(mFlinger->mStateLock) { surfaceFrame->setAcquireFenceTime(acquireFenceTime); surfaceFrame->setPresentState(PresentState::Presented, mLastLatchTime); mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame); @@ -466,7 +467,8 @@ void Layer::addSurfaceFramePresentedForBuffer( } std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransaction( - const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode) { + const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode) + REQUIRES(mFlinger->mStateLock) { auto surfaceFrame = mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid, getSequence(), mName, @@ -488,7 +490,7 @@ std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransac std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer( const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName, - gui::GameMode gameMode) { + gui::GameMode gameMode) REQUIRES(mFlinger->mStateLock) { auto surfaceFrame = mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid, getSequence(), mName, debugName, @@ -506,7 +508,8 @@ std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer( } void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime, - std::string debugName, gui::GameMode gameMode) { + std::string debugName, gui::GameMode gameMode) + REQUIRES(mFlinger->mStateLock) { if (info.skippedFrameVsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) { return; } @@ -842,7 +845,7 @@ bool Layer::setTransformToDisplayInverse(bool transformToDisplayInverse) { return true; } -void Layer::releasePreviousBuffer() { +void Layer::releasePreviousBuffer() REQUIRES(mFlinger->mStateLock) { mReleasePreviousBuffer = true; if (!mBufferInfo.mBuffer || (!mDrawingState.buffer->hasSameBuffer(*mBufferInfo.mBuffer) || @@ -884,7 +887,8 @@ void Layer::resetDrawingStateBufferInfo() { bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer, const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime, - bool isAutoTimestamp, const FrameTimelineInfo& info, gui::GameMode gameMode) { + bool isAutoTimestamp, const FrameTimelineInfo& info, gui::GameMode gameMode) + REQUIRES(mFlinger->mStateLock) { SFTRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false")); const bool frameNumberChanged = @@ -1074,7 +1078,8 @@ bool Layer::setDesiredHdrHeadroom(float desiredRatio) { } bool Layer::setSidebandStream(const sp<NativeHandle>& sidebandStream, const FrameTimelineInfo& info, - nsecs_t postTime, gui::GameMode gameMode) { + nsecs_t postTime, gui::GameMode gameMode) + REQUIRES(mFlinger->mStateLock) { if (mDrawingState.sidebandStream == sidebandStream) return false; if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) { @@ -1207,7 +1212,7 @@ bool Layer::latchSidebandStream(bool& recomputeVisibleRegions) { return false; } -void Layer::updateTexImage(nsecs_t latchTime, bool bgColorOnly) { +void Layer::updateTexImage(nsecs_t latchTime, bool bgColorOnly) REQUIRES(mFlinger->mStateLock) { const State& s(getDrawingState()); if (!s.buffer) { @@ -1428,8 +1433,8 @@ void Layer::onCompositionPresented(const DisplayDevice* display, presentFence, FrameTracer::FrameEvent::PRESENT_FENCE); mDeprecatedFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence)); - } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId()); - displayId && mFlinger->getHwComposer().isConnected(*displayId)) { + } else if (const auto displayId = asPhysicalDisplayId(display->getDisplayIdVariant()); + displayId.has_value() && mFlinger->getHwComposer().isConnected(*displayId)) { // The HWC doesn't support present fences, so use the present timestamp instead. const nsecs_t presentTimestamp = mFlinger->getHwComposer().getPresentTimestamp(*displayId); @@ -1457,7 +1462,8 @@ void Layer::onCompositionPresented(const DisplayDevice* display, mBufferInfo.mFrameLatencyNeeded = false; } -bool Layer::latchBufferImpl(bool& recomputeVisibleRegions, nsecs_t latchTime, bool bgColorOnly) { +bool Layer::latchBufferImpl(bool& recomputeVisibleRegions, nsecs_t latchTime, bool bgColorOnly) + REQUIRES(mFlinger->mStateLock) { SFTRACE_FORMAT_INSTANT("latchBuffer %s - %" PRIu64, getDebugName(), getDrawingState().frameNumber); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c234a75693..081bb22246 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -288,7 +288,7 @@ public: bool leaveState); inline bool hasTrustedPresentationListener() { - return mTrustedPresentationListener.callbackInterface != nullptr; + return mTrustedPresentationListener.getCallback() != nullptr; } // Sets the masked bits. @@ -516,11 +516,6 @@ private: bool mGetHandleCalled = false; - // The inherited shadow radius after taking into account the layer hierarchy. This is the - // final shadow radius for this layer. If a shadow is specified for a layer, then effective - // shadow radius is the set shadow radius, otherwise its the parent's shadow radius. - float mEffectiveShadowRadius = 0.f; - // Game mode for the layer. Set by WindowManagerShell and recorded by SurfaceFlingerStats. gui::GameMode mGameMode = gui::GameMode::Unsupported; diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp index fea7671af2..b6192685ae 100644 --- a/services/surfaceflinger/LayerFE.cpp +++ b/services/surfaceflinger/LayerFE.cpp @@ -173,7 +173,7 @@ std::optional<compositionengine::LayerFE::LayerSettings> LayerFE::prepareClientC layerSettings.edgeExtensionEffect = mSnapshot->edgeExtensionEffect; // Record the name of the layer for debugging further down the stack. layerSettings.name = mSnapshot->name; - layerSettings.luts = mSnapshot->luts; + layerSettings.luts = mSnapshot->luts ? mSnapshot->luts : targetSettings.luts; if (hasEffect() && !hasBufferOrSidebandStream()) { prepareEffectsClientComposition(layerSettings, targetSettings); @@ -191,6 +191,7 @@ void LayerFE::prepareClearClientComposition(LayerFE::LayerSettings& layerSetting layerSettings.disableBlending = true; layerSettings.bufferId = 0; layerSettings.frameNumber = 0; + layerSettings.sequence = -1; // If layer is blacked out, force alpha to 1 so that we draw a black color layer. layerSettings.alpha = blackout ? 1.0f : 0.0f; @@ -262,6 +263,7 @@ void LayerFE::prepareBufferStateClientComposition( layerSettings.source.buffer.maxLuminanceNits = maxLuminance; layerSettings.frameNumber = mSnapshot->frameNumber; layerSettings.bufferId = mSnapshot->externalTexture->getId(); + layerSettings.sequence = mSnapshot->sequence; const bool useFiltering = targetSettings.needsFiltering || mSnapshot->geomLayerTransform.needsBilinearFiltering(); @@ -425,4 +427,13 @@ ftl::Future<FenceResult> LayerFE::createReleaseFenceFuture() { LayerFE::ReleaseFencePromiseStatus LayerFE::getReleaseFencePromiseStatus() { return mReleaseFencePromiseStatus; } + +void LayerFE::setLastHwcState(const LayerFE::HwcLayerDebugState &state) { + mLastHwcState = state; +} + +const LayerFE::HwcLayerDebugState& LayerFE::getLastHwcState() const { + return mLastHwcState; +}; + } // namespace android diff --git a/services/surfaceflinger/LayerFE.h b/services/surfaceflinger/LayerFE.h index 9483aebafa..a537456beb 100644 --- a/services/surfaceflinger/LayerFE.h +++ b/services/surfaceflinger/LayerFE.h @@ -60,6 +60,10 @@ public: LayerFE::ReleaseFencePromiseStatus getReleaseFencePromiseStatus() override; void onPictureProfileCommitted() override; + // Used for debugging purposes, e.g. perfetto tracing, dumpsys. + void setLastHwcState(const HwcLayerDebugState &state) override; + const HwcLayerDebugState &getLastHwcState() const override; + std::unique_ptr<surfaceflinger::frontend::LayerSnapshot> mSnapshot; private: @@ -90,6 +94,7 @@ private: std::string mName; std::promise<FenceResult> mReleaseFence; ReleaseFencePromiseStatus mReleaseFencePromiseStatus = ReleaseFencePromiseStatus::UNINITIALIZED; + HwcLayerDebugState mLastHwcState; }; } // namespace android diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp index 44cd3194bc..84b1a73e0b 100644 --- a/services/surfaceflinger/LayerProtoHelper.cpp +++ b/services/surfaceflinger/LayerProtoHelper.cpp @@ -447,7 +447,7 @@ void LayerProtoHelper::writeSnapshotToProto(perfetto::protos::LayerProto* layerI } layerInfo->set_type("Layer"); - LayerProtoHelper::writeToProto(requestedState.transparentRegion, + LayerProtoHelper::writeToProto(requestedState.getTransparentRegion(), [&]() { return layerInfo->mutable_transparent_region(); }); layerInfo->set_layer_stack(snapshot.outputFilter.layerStack.id); diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp deleted file mode 100644 index bfe6d2a956..0000000000 --- a/services/surfaceflinger/LayerRenderArea.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <ui/GraphicTypes.h> -#include <ui/Transform.h> - -#include "DisplayDevice.h" -#include "FrontEnd/LayerCreationArgs.h" -#include "Layer.h" -#include "LayerRenderArea.h" -#include "SurfaceFlinger.h" - -namespace android { - -LayerRenderArea::LayerRenderArea(sp<Layer> layer, frontend::LayerSnapshot layerSnapshot, - const Rect& crop, ui::Size reqSize, ui::Dataspace reqDataSpace, - const ui::Transform& layerTransform, const Rect& layerBufferSize, - ftl::Flags<RenderArea::Options> options) - : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, options), - mLayer(std::move(layer)), - mLayerSnapshot(std::move(layerSnapshot)), - mLayerBufferSize(layerBufferSize), - mCrop(crop), - mTransform(layerTransform) {} - -const ui::Transform& LayerRenderArea::getTransform() const { - return mTransform; -} - -bool LayerRenderArea::isSecure() const { - return mOptions.test(Options::CAPTURE_SECURE_LAYERS); -} - -sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const { - return nullptr; -} - -Rect LayerRenderArea::getSourceCrop() const { - if (mCrop.isEmpty()) { - // TODO this should probably be mBounds instead of just buffer bounds - return mLayerBufferSize; - } else { - return mCrop; - } -} - -} // namespace android diff --git a/services/surfaceflinger/LayerRenderArea.h b/services/surfaceflinger/LayerRenderArea.h deleted file mode 100644 index f72c7c7715..0000000000 --- a/services/surfaceflinger/LayerRenderArea.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <string> - -#include <ui/GraphicTypes.h> -#include <ui/Transform.h> -#include <utils/StrongPointer.h> - -#include "RenderArea.h" - -namespace android { - -class DisplayDevice; -class Layer; -class SurfaceFlinger; - -class LayerRenderArea : public RenderArea { -public: - LayerRenderArea(sp<Layer> layer, frontend::LayerSnapshot layerSnapshot, const Rect& crop, - ui::Size reqSize, ui::Dataspace reqDataSpace, - const ui::Transform& layerTransform, const Rect& layerBufferSize, - ftl::Flags<RenderArea::Options> options); - - const ui::Transform& getTransform() const override; - bool isSecure() const override; - sp<const DisplayDevice> getDisplayDevice() const override; - Rect getSourceCrop() const override; - - sp<Layer> getParentLayer() const override { return mLayer; } - const frontend::LayerSnapshot* getLayerSnapshot() const override { return &mLayerSnapshot; } - -private: - const sp<Layer> mLayer; - const frontend::LayerSnapshot mLayerSnapshot; - const Rect mLayerBufferSize; - const Rect mCrop; - - ui::Transform mTransform; -}; - -} // namespace android diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS index fa0ecee6b5..13edd1668e 100644 --- a/services/surfaceflinger/OWNERS +++ b/services/surfaceflinger/OWNERS @@ -12,6 +12,5 @@ racarr@google.com ramindani@google.com rnlee@google.com sallyqi@google.com -scroggo@google.com vishnun@google.com xwxw@google.com diff --git a/services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp b/services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp index ff452723d5..788448d079 100644 --- a/services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp +++ b/services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp @@ -29,7 +29,9 @@ #include <android-base/properties.h> #include <android/binder_libbinder.h> +#include <common/WorkloadTracer.h> #include <common/trace.h> +#include <ftl/concat.h> #include <utils/Log.h> #include <utils/Mutex.h> @@ -44,6 +46,7 @@ namespace android::adpf::impl { +using namespace android::ftl::flag_operators; using aidl::android::hardware::common::fmq::SynchronizedReadWrite; using android::hardware::EventFlag; @@ -62,6 +65,8 @@ void traceExpensiveRendering(bool enabled) { } } +static constexpr ftl::Flags<Workload> TRIGGER_LOAD_CHANGE_HINTS = Workload::EFFECTS | + Workload::VISIBLE_REGION | Workload::DISPLAY_CHANGES | Workload::SCREENSHOT; } // namespace PowerAdvisor::PowerAdvisor(std::function<void()>&& sfDisableExpensiveFn, @@ -510,7 +515,7 @@ void PowerAdvisor::setRequiresRenderEngine(DisplayId displayId, bool requiresRen } void PowerAdvisor::setExpectedPresentTime(TimePoint expectedPresentTime) { - mExpectedPresentTimes.append(expectedPresentTime); + mExpectedPresentTimes.next() = expectedPresentTime; } void PowerAdvisor::setSfPresentTiming(TimePoint presentFenceTime, TimePoint presentEndTime) { @@ -527,7 +532,7 @@ void PowerAdvisor::setHwcPresentDelayedTime(DisplayId displayId, TimePoint earli } void PowerAdvisor::setCommitStart(TimePoint commitStartTime) { - mCommitStartTimes.append(commitStartTime); + mCommitStartTimes.next() = commitStartTime; } void PowerAdvisor::setCompositeEnd(TimePoint compositeEndTime) { @@ -574,7 +579,7 @@ std::optional<hal::WorkDuration> PowerAdvisor::estimateWorkDuration() { } // Tracks when we finish presenting to hwc - TimePoint estimatedHwcEndTime = mCommitStartTimes[0]; + TimePoint estimatedHwcEndTime = mCommitStartTimes.back(); // How long we spent this frame not doing anything, waiting for fences or vsync Duration idleDuration = 0ns; @@ -638,13 +643,13 @@ std::optional<hal::WorkDuration> PowerAdvisor::estimateWorkDuration() { // Also add the frame delay duration since the target did not move while we were delayed Duration totalDuration = mFrameDelayDuration + std::max(estimatedHwcEndTime, estimatedGpuEndTime.value_or(TimePoint{0ns})) - - mCommitStartTimes[0]; + mCommitStartTimes.back(); Duration totalDurationWithoutGpu = - mFrameDelayDuration + estimatedHwcEndTime - mCommitStartTimes[0]; + mFrameDelayDuration + estimatedHwcEndTime - mCommitStartTimes.back(); // We finish SurfaceFlinger when post-composition finishes, so add that in here Duration flingerDuration = - estimatedFlingerEndTime + mLastPostcompDuration - mCommitStartTimes[0]; + estimatedFlingerEndTime + mLastPostcompDuration - mCommitStartTimes.back(); Duration estimatedGpuDuration = firstGpuTimeline.has_value() ? estimatedGpuEndTime.value_or(TimePoint{0ns}) - firstGpuTimeline->startTime : Duration::fromNs(0); @@ -656,7 +661,7 @@ std::optional<hal::WorkDuration> PowerAdvisor::estimateWorkDuration() { hal::WorkDuration duration{ .timeStampNanos = TimePoint::now().ns(), .durationNanos = combinedDuration.ns(), - .workPeriodStartTimestampNanos = mCommitStartTimes[0].ns(), + .workPeriodStartTimestampNanos = mCommitStartTimes.back().ns(), .cpuDurationNanos = supportsGpuReporting() ? cpuDuration.ns() : 0, .gpuDurationNanos = supportsGpuReporting() ? estimatedGpuDuration.ns() : 0, }; @@ -756,4 +761,58 @@ power::PowerHalController& PowerAdvisor::getPowerHal() { return *mPowerHal; } +void PowerAdvisor::setQueuedWorkload(ftl::Flags<Workload> queued) { + queued &= TRIGGER_LOAD_CHANGE_HINTS; + if (!(queued).get()) return; + uint32_t previousQueuedWorkload = mQueuedWorkload.fetch_or(queued.get()); + + uint32_t newHints = (previousQueuedWorkload ^ queued.get()) & queued.get(); + if (newHints) { + SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME, + ftl::Concat("QueuedWorkload: ", + ftl::truncated<20>(ftl::Flags<Workload>(newHints) + .string() + .c_str())) + .c_str()); + } + if (!previousQueuedWorkload) { + // TODO(b/385028458) maybe load up hint if close to wake up + } +} + +void PowerAdvisor::setScreenshotWorkload() { + mCommittedWorkload |= Workload::SCREENSHOT; +} + +void PowerAdvisor::setCommittedWorkload(ftl::Flags<Workload> workload) { + workload &= TRIGGER_LOAD_CHANGE_HINTS; + uint32_t queued = mQueuedWorkload.exchange(0); + mCommittedWorkload |= workload; + + bool cancelLoadupHint = queued && !mCommittedWorkload.get(); + if (cancelLoadupHint) { + SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME, + ftl::Concat("UncommittedQueuedWorkload: ", + ftl::truncated<20>(ftl::Flags<Workload>(queued) + .string() + .c_str())) + .c_str()); + // TODO(b/385028458) cancel load up hint + } + + bool increasedWorkload = queued == 0 && mCommittedWorkload.get() != 0; + if (increasedWorkload) { + SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME, + ftl::Concat("CommittedWorkload: ", + ftl::truncated<20>(mCommittedWorkload.string())) + .c_str()); + + // TODO(b/385028458) load up hint + } +} + +void PowerAdvisor::setCompositedWorkload(ftl::Flags<Workload> composited) { + composited &= TRIGGER_LOAD_CHANGE_HINTS; + mCommittedWorkload = composited; +} } // namespace android::adpf::impl diff --git a/services/surfaceflinger/PowerAdvisor/PowerAdvisor.h b/services/surfaceflinger/PowerAdvisor/PowerAdvisor.h index 43fc21093f..b97160a3e5 100644 --- a/services/surfaceflinger/PowerAdvisor/PowerAdvisor.h +++ b/services/surfaceflinger/PowerAdvisor/PowerAdvisor.h @@ -23,6 +23,7 @@ #include <ui/DisplayId.h> #include <ui/FenceTime.h> +#include <ui/RingBuffer.h> #include <utils/Mutex.h> // FMQ library in IPower does questionable conversions @@ -32,9 +33,12 @@ #include <fmq/AidlMessageQueue.h> #pragma clang diagnostic pop +#include <common/trace.h> +#include <ftl/flags.h> #include <scheduler/Time.h> #include <ui/DisplayIdentification.h> #include "../Scheduler/OneShotTimer.h" +#include "Workload.h" #include "SessionManager.h" @@ -109,6 +113,26 @@ public: // Get the session manager, if it exists virtual std::shared_ptr<SessionManager> getSessionManager() = 0; + // --- Track per frame workloads to use for load up hint heuristics + // Track queued workload from transactions as they are queued from the binder thread. + // The workload is accumulated and reset on frame commit. The queued workload may be + // relevant for the next frame so can be used as an early load up hint. Note this is + // only a hint because the transaction can remain in the queue and not be applied on + // the next frame. + virtual void setQueuedWorkload(ftl::Flags<Workload> workload) = 0; + // Track additional workload dur to a screenshot request for load up hint heuristics. This + // would indicate an immediate increase in GPU workload. + virtual void setScreenshotWorkload() = 0; + // Track committed workload from transactions that are applied on the main thread. + // This workload is determined from the applied transactions. This can provide a high + // confidence that the CPU and or GPU workload will increase immediately. + virtual void setCommittedWorkload(ftl::Flags<Workload> workload) = 0; + // Update committed workload with the actual workload from post composition. This is + // used to update the baseline workload so we can detect increases in workloads on the + // next commit. We use composite instead of commit to update the baseline to account + // for optimizations like caching which may reduce the workload. + virtual void setCompositedWorkload(ftl::Flags<Workload> workload) = 0; + // --- The following methods may run on threads besides SF main --- // Send a hint about an upcoming increase in the CPU workload virtual void notifyCpuLoadUp() = 0; @@ -158,6 +182,11 @@ public: void setTotalFrameTargetWorkDuration(Duration targetDuration) override; std::shared_ptr<SessionManager> getSessionManager() override; + void setQueuedWorkload(ftl::Flags<Workload> workload) override; + void setScreenshotWorkload() override; + void setCommittedWorkload(ftl::Flags<Workload> workload) override; + void setCompositedWorkload(ftl::Flags<Workload> workload) override; + // --- The following methods may run on threads besides SF main --- void notifyCpuLoadUp() override; void notifyDisplayUpdateImminentAndCpuReset() override; @@ -219,27 +248,6 @@ private: std::optional<GpuTimeline> estimateGpuTiming(std::optional<TimePoint> previousEndTime); }; - template <class T, size_t N> - class RingBuffer { - std::array<T, N> elements = {}; - size_t mIndex = 0; - size_t numElements = 0; - - public: - void append(T item) { - mIndex = (mIndex + 1) % N; - numElements = std::min(N, numElements + 1); - elements[mIndex] = item; - } - bool isFull() const { return numElements == N; } - // Allows access like [0] == current, [-1] = previous, etc.. - T& operator[](int offset) { - size_t positiveOffset = - static_cast<size_t>((offset % static_cast<int>(N)) + static_cast<int>(N)); - return elements[(mIndex + positiveOffset) % N]; - } - }; - // Filter and sort the display ids by a given property std::vector<DisplayId> getOrderedDisplayIds( std::optional<TimePoint> DisplayTimingData::*sortBy); @@ -259,9 +267,9 @@ private: // Last frame's post-composition duration Duration mLastPostcompDuration{0ns}; // Buffer of recent commit start times - RingBuffer<TimePoint, 2> mCommitStartTimes; + ui::RingBuffer<TimePoint, 2> mCommitStartTimes; // Buffer of recent expected present times - RingBuffer<TimePoint, 2> mExpectedPresentTimes; + ui::RingBuffer<TimePoint, 2> mExpectedPresentTimes; // Most recent present fence time, provided by SF after composition engine finishes presenting TimePoint mLastPresentFenceTime; // Most recent composition engine present end time, returned with the present fence from SF @@ -332,6 +340,11 @@ private: static constexpr const Duration kFenceWaitStartDelayValidated{150us}; static constexpr const Duration kFenceWaitStartDelaySkippedValidate{250us}; + // Track queued and committed workloads per frame. Queued workload is atomic because it's + // updated on both binder and the main thread. + std::atomic<uint32_t> mQueuedWorkload; + ftl::Flags<Workload> mCommittedWorkload; + void sendHintSessionHint(aidl::android::hardware::power::SessionHint hint); template <aidl::android::hardware::power::ChannelMessage::ChannelMessageContents::Tag T, diff --git a/services/surfaceflinger/PowerAdvisor/Workload.h b/services/surfaceflinger/PowerAdvisor/Workload.h new file mode 100644 index 0000000000..70023579f8 --- /dev/null +++ b/services/surfaceflinger/PowerAdvisor/Workload.h @@ -0,0 +1,44 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <ftl/flags.h> +#include <stdint.h> + +namespace android::adpf { +// Additional composition workload that can increase cpu load. +enum class Workload : uint32_t { + NONE = 0, + // Layer effects like blur and shadows which forces client composition + EFFECTS = 1 << 0, + + // Geometry changes which requires HWC to validate and share composition strategy + VISIBLE_REGION = 1 << 1, + + // Diplay changes which can cause geometry changes + DISPLAY_CHANGES = 1 << 2, + + // Changes in sf duration which can shorten the deadline for sf to composite the frame + WAKEUP = 1 << 3, + + // Increases in refresh rates can cause the deadline for sf to composite to be shorter + REFRESH_RATE_INCREASE = 1 << 4, + + // Screenshot requests increase both the cpu and gpu workload + SCREENSHOT = 1 << 5 +}; +} // namespace android::adpf diff --git a/services/surfaceflinger/QueuedTransactionState.h b/services/surfaceflinger/QueuedTransactionState.h index af40c026a0..6a17a0d0cb 100644 --- a/services/surfaceflinger/QueuedTransactionState.h +++ b/services/surfaceflinger/QueuedTransactionState.h @@ -21,8 +21,11 @@ #include "FrontEnd/LayerCreationArgs.h" #include "renderengine/ExternalTexture.h" +#include <PowerAdvisor/Workload.h> #include <common/FlagManager.h> +#include <ftl/flags.h> #include <gui/LayerState.h> +#include <gui/TransactionState.h> #include <system/window.h> namespace android { @@ -48,33 +51,26 @@ public: struct QueuedTransactionState { QueuedTransactionState() = default; - QueuedTransactionState(const FrameTimelineInfo& frameTimelineInfo, - std::vector<ResolvedComposerState>& composerStates, - const Vector<DisplayState>& displayStates, uint32_t transactionFlags, - const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands, - int64_t desiredPresentTime, bool isAutoTimestamp, - std::vector<uint64_t> uncacheBufferIds, int64_t postTime, - bool hasListenerCallbacks, - std::vector<ListenerCallbacks> listenerCallbacks, int originPid, - int originUid, uint64_t transactionId, - std::vector<uint64_t> mergedTransactionIds) - : frameTimelineInfo(frameTimelineInfo), - states(std::move(composerStates)), - displays(displayStates), - flags(transactionFlags), - applyToken(applyToken), - inputWindowCommands(inputWindowCommands), - desiredPresentTime(desiredPresentTime), - isAutoTimestamp(isAutoTimestamp), + QueuedTransactionState(TransactionState&& transactionState, + std::vector<ResolvedComposerState>&& composerStates, + std::vector<uint64_t>&& uncacheBufferIds, int64_t postTime, + int originPid, int originUid) + : frameTimelineInfo(std::move(transactionState.mFrameTimelineInfo)), + states(composerStates), + displays(std::move(transactionState.mDisplayStates)), + flags(transactionState.mFlags), + applyToken(transactionState.mApplyToken), + inputWindowCommands(std::move(transactionState.mInputWindowCommands)), + desiredPresentTime(transactionState.mDesiredPresentTime), + isAutoTimestamp(transactionState.mIsAutoTimestamp), uncacheBufferIds(std::move(uncacheBufferIds)), postTime(postTime), - hasListenerCallbacks(hasListenerCallbacks), - listenerCallbacks(listenerCallbacks), + hasListenerCallbacks(transactionState.mHasListenerCallbacks), + listenerCallbacks(std::move(transactionState.mListenerCallbacks)), originPid(originPid), originUid(originUid), - id(transactionId), - mergedTransactionIds(std::move(mergedTransactionIds)) {} + id(transactionState.getId()), + mergedTransactionIds(std::move(transactionState.mMergedTransactionIds)) {} // Invokes `void(const layer_state_t&)` visitor for matching layers. template <typename Visitor> @@ -133,7 +129,7 @@ struct QueuedTransactionState { FrameTimelineInfo frameTimelineInfo; std::vector<ResolvedComposerState> states; - Vector<DisplayState> displays; + std::vector<DisplayState> displays; uint32_t flags; sp<IBinder> applyToken; InputWindowCommands inputWindowCommands; @@ -148,6 +144,7 @@ struct QueuedTransactionState { uint64_t id; bool sentFenceTimeoutWarning = false; std::vector<uint64_t> mergedTransactionIds; + ftl::Flags<adpf::Workload> workloadHint; }; } // namespace android diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp index d3483b0cb0..615492a872 100644 --- a/services/surfaceflinger/RegionSamplingThread.cpp +++ b/services/surfaceflinger/RegionSamplingThread.cpp @@ -39,11 +39,8 @@ #include <string> #include "DisplayDevice.h" -#include "DisplayRenderArea.h" #include "FrontEnd/LayerCreationArgs.h" #include "Layer.h" -#include "RenderAreaBuilder.h" -#include "Scheduler/VsyncController.h" #include "SurfaceFlinger.h" namespace android { @@ -259,6 +256,7 @@ void RegionSamplingThread::captureSample() { ui::LayerStack layerStack; ui::Transform::RotationFlags orientation; ui::Size displaySize; + Rect layerStackSpaceRect; { // TODO(b/159112860): Don't keep sp<DisplayDevice> outside of SF main thread @@ -267,6 +265,7 @@ void RegionSamplingThread::captureSample() { layerStack = display->getLayerStack(); orientation = ui::Transform::toRotationFlags(display->getOrientation()); displaySize = display->getSize(); + layerStackSpaceRect = display->getLayerStackSpaceRect(); } std::vector<RegionSamplingThread::Descriptor> descriptors; @@ -347,18 +346,20 @@ void RegionSamplingThread::captureSample() { constexpr bool kGrayscale = false; constexpr bool kIsProtected = false; - SurfaceFlinger::RenderAreaBuilderVariant - renderAreaBuilder(std::in_place_type<DisplayRenderAreaBuilder>, sampledBounds, - sampledBounds.getSize(), ui::Dataspace::V0_SRGB, displayWeak, - RenderArea::Options::CAPTURE_SECURE_LAYERS); + SurfaceFlinger::ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = displayWeak; + screenshotArgs.displayIdVariant = std::nullopt; + screenshotArgs.sourceCrop = sampledBounds.isEmpty() ? layerStackSpaceRect : sampledBounds; + screenshotArgs.reqSize = sampledBounds.getSize(); + screenshotArgs.dataspace = ui::Dataspace::V0_SRGB; + screenshotArgs.isSecure = true; + screenshotArgs.seamlessTransition = false; std::vector<std::pair<Layer*, sp<LayerFE>>> layers; - auto displayState = - mFlinger.getSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, layers); - FenceResult fenceResult = - mFlinger.captureScreenshot(renderAreaBuilder, buffer, kRegionSampling, kGrayscale, - kIsProtected, nullptr, displayState, layers) - .get(); + mFlinger.getSnapshotsFromMainThread(screenshotArgs, getLayerSnapshotsFn, layers); + FenceResult fenceResult = mFlinger.captureScreenshot(screenshotArgs, buffer, kRegionSampling, + kGrayscale, kIsProtected, nullptr, layers) + .get(); if (fenceResult.ok()) { fenceResult.value()->waitForever(LOG_TAG); } diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h deleted file mode 100644 index aa66ccf172..0000000000 --- a/services/surfaceflinger/RenderArea.h +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once - -#include <ui/GraphicTypes.h> -#include <ui/Transform.h> - -#include <functional> - -#include "FrontEnd/LayerSnapshot.h" -#include "Layer.h" - -namespace android { - -class DisplayDevice; - -// RenderArea describes a rectangular area that layers can be rendered to. -// -// There is a logical render area and a physical render area. When a layer is -// rendered to the render area, it is first transformed and clipped to the logical -// render area. The transformed and clipped layer is then projected onto the -// physical render area. -class RenderArea { -public: - enum class CaptureFill {CLEAR, OPAQUE}; - enum class Options { - // If not set, the secure layer would be blacked out or skipped - // when rendered to an insecure render area - CAPTURE_SECURE_LAYERS = 1 << 0, - - // If set, the render result may be used for system animations - // that must preserve the exact colors of the display - HINT_FOR_SEAMLESS_TRANSITION = 1 << 1, - }; - static float getCaptureFillValue(CaptureFill captureFill); - - RenderArea(ui::Size reqSize, CaptureFill captureFill, ui::Dataspace reqDataSpace, - ftl::Flags<Options> options) - : mOptions(options), - mReqSize(reqSize), - mReqDataSpace(reqDataSpace), - mCaptureFill(captureFill) {} - - virtual ~RenderArea() = default; - - // Returns true if the render area is secure. A secure layer should be - // blacked out / skipped when rendered to an insecure render area. - virtual bool isSecure() const = 0; - - // Returns the transform to be applied on layers to transform them into - // the logical render area. - virtual const ui::Transform& getTransform() const = 0; - - // Returns the source crop of the render area. The source crop defines - // how layers are projected from the logical render area onto the physical - // render area. It can be larger than the logical render area. It can - // also be optionally rotated. - // - // The source crop is specified in layer space (when rendering a layer and - // its children), or in layer-stack space (when rendering all layers visible - // on the display). - virtual Rect getSourceCrop() const = 0; - - // Returns the size of the physical render area. - int getReqWidth() const { return mReqSize.width; } - int getReqHeight() const { return mReqSize.height; } - - // Returns the composition data space of the render area. - ui::Dataspace getReqDataSpace() const { return mReqDataSpace; } - - // Returns the fill color of the physical render area. Regions not - // covered by any rendered layer should be filled with this color. - CaptureFill getCaptureFill() const { return mCaptureFill; } - - virtual sp<const DisplayDevice> getDisplayDevice() const = 0; - - // If this is a LayerRenderArea, return the root layer of the - // capture operation. - virtual sp<Layer> getParentLayer() const { return nullptr; } - - // If this is a LayerRenderArea, return the layer snapshot - // of the root layer of the capture operation - virtual const frontend::LayerSnapshot* getLayerSnapshot() const { return nullptr; } - - // Returns whether the render result may be used for system animations that - // must preserve the exact colors of the display. - bool getHintForSeamlessTransition() const { - return mOptions.test(Options::HINT_FOR_SEAMLESS_TRANSITION); - } - -protected: - ftl::Flags<Options> mOptions; - -private: - const ui::Size mReqSize; - const ui::Dataspace mReqDataSpace; - const CaptureFill mCaptureFill; -}; - -} // namespace android diff --git a/services/surfaceflinger/RenderAreaBuilder.h b/services/surfaceflinger/RenderAreaBuilder.h deleted file mode 100644 index 599fa7e102..0000000000 --- a/services/surfaceflinger/RenderAreaBuilder.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "DisplayDevice.h" -#include "DisplayRenderArea.h" -#include "LayerRenderArea.h" -#include "ui/Size.h" -#include "ui/Transform.h" - -namespace android { -/** - * A parameter object for creating a render area - */ -struct RenderAreaBuilder { - // Source crop of the render area - Rect crop; - - // Size of the physical render area - ui::Size reqSize; - - // Composition data space of the render area - ui::Dataspace reqDataSpace; - - ftl::Flags<RenderArea::Options> options; - virtual std::unique_ptr<RenderArea> build() const = 0; - - RenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace, - ftl::Flags<RenderArea::Options> options) - : crop(crop), reqSize(reqSize), reqDataSpace(reqDataSpace), options(options) {} - - virtual ~RenderAreaBuilder() = default; -}; - -struct DisplayRenderAreaBuilder : RenderAreaBuilder { - DisplayRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace, - wp<const DisplayDevice> displayWeak, - ftl::Flags<RenderArea::Options> options) - : RenderAreaBuilder(crop, reqSize, reqDataSpace, options), displayWeak(displayWeak) {} - - // Display that render area will be on - wp<const DisplayDevice> displayWeak; - - std::unique_ptr<RenderArea> build() const override { - return DisplayRenderArea::create(displayWeak, crop, reqSize, reqDataSpace, options); - } -}; - -struct LayerRenderAreaBuilder : RenderAreaBuilder { - LayerRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace, sp<Layer> layer, - bool childrenOnly, ftl::Flags<RenderArea::Options> options) - : RenderAreaBuilder(crop, reqSize, reqDataSpace, options), - layer(layer), - childrenOnly(childrenOnly) {} - - // Root layer of the render area - sp<Layer> layer; - - // Layer snapshot of the root layer - frontend::LayerSnapshot layerSnapshot; - - // Transform to be applied on the layers to transform them - // into the logical render area - ui::Transform layerTransform{ui::Transform()}; - - // Buffer bounds - Rect layerBufferSize{Rect()}; - - // If false, transform is inverted from the parent snapshot - bool childrenOnly; - - // Uses parent snapshot to determine layer transform and buffer size - void setLayerSnapshot(const frontend::LayerSnapshot& parentSnapshot) { - layerSnapshot = parentSnapshot; - if (!childrenOnly) { - layerTransform = parentSnapshot.localTransform.inverse(); - } - layerBufferSize = parentSnapshot.bufferSize; - } - - std::unique_ptr<RenderArea> build() const override { - return std::make_unique<LayerRenderArea>(layer, std::move(layerSnapshot), crop, reqSize, - reqDataSpace, layerTransform, layerBufferSize, - options); - } -}; - -} // namespace android
\ No newline at end of file diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index c6d7160818..c37b9653cb 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -45,7 +45,7 @@ #include <common/FlagManager.h> #include <scheduler/FrameRateMode.h> #include <scheduler/VsyncConfig.h> -#include "FrameTimeline.h" +#include "FrameTimeline/FrameTimeline.h" #include "VSyncDispatch.h" #include "EventThread.h" @@ -86,36 +86,43 @@ std::string toString(const EventThreadConnection& connection) { std::string toString(const DisplayEventReceiver::Event& event) { switch (event.header.type) { - case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: + case DisplayEventType::DISPLAY_EVENT_HOTPLUG: return StringPrintf("Hotplug{displayId=%s, %s}", to_string(event.header.displayId).c_str(), event.hotplug.connected ? "connected" : "disconnected"); - case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: + case DisplayEventType::DISPLAY_EVENT_VSYNC: return StringPrintf("VSync{displayId=%s, count=%u, expectedPresentationTime=%" PRId64 "}", to_string(event.header.displayId).c_str(), event.vsync.count, event.vsync.vsyncData.preferredExpectedPresentationTime()); - case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: + case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE: return StringPrintf("ModeChanged{displayId=%s, modeId=%u}", to_string(event.header.displayId).c_str(), event.modeChange.modeId); - case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE: + case DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE: return StringPrintf("HdcpLevelsChange{displayId=%s, connectedLevel=%d, maxLevel=%d}", to_string(event.header.displayId).c_str(), event.hdcpLevelsChange.connectedLevel, event.hdcpLevelsChange.maxLevel); - case DisplayEventReceiver::DISPLAY_EVENT_MODE_REJECTION: + case DisplayEventType::DISPLAY_EVENT_MODE_REJECTION: return StringPrintf("ModeRejected{displayId=%s, modeId=%u}", to_string(event.header.displayId).c_str(), event.modeRejection.modeId); - default: - return "Event{}"; + case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE: + return StringPrintf("FrameRateOverride{displayId=%s, frameRateHz=%f}", + to_string(event.header.displayId).c_str(), + event.frameRateOverride.frameRateHz); + case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH: + return StringPrintf("FrameRateOverrideFlush{displayId=%s}", + to_string(event.header.displayId).c_str()); + case DisplayEventType::DISPLAY_EVENT_NULL: + return "NULL"; } } DisplayEventReceiver::Event makeHotplug(PhysicalDisplayId displayId, nsecs_t timestamp, bool connected) { DisplayEventReceiver::Event event; - event.header = {DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, displayId, timestamp}; + event.header = {DisplayEventType::DISPLAY_EVENT_HOTPLUG, displayId, timestamp}; event.hotplug.connected = connected; return event; } @@ -123,7 +130,7 @@ DisplayEventReceiver::Event makeHotplug(PhysicalDisplayId displayId, nsecs_t tim DisplayEventReceiver::Event makeHotplugError(nsecs_t timestamp, int32_t connectionError) { DisplayEventReceiver::Event event; PhysicalDisplayId unusedDisplayId; - event.header = {DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, unusedDisplayId, timestamp}; + event.header = {DisplayEventType::DISPLAY_EVENT_HOTPLUG, unusedDisplayId, timestamp}; event.hotplug.connected = false; event.hotplug.connectionError = connectionError; return event; @@ -133,7 +140,7 @@ DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t times uint32_t count, nsecs_t expectedPresentationTime, nsecs_t deadlineTimestamp) { DisplayEventReceiver::Event event; - event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp}; + event.header = {DisplayEventType::DISPLAY_EVENT_VSYNC, displayId, timestamp}; event.vsync.count = count; event.vsync.vsyncData.preferredFrameTimelineIndex = 0; // Temporarily store the current vsync information in frameTimelines[0], marked as @@ -148,7 +155,7 @@ DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t times DisplayEventReceiver::Event makeModeChanged(const scheduler::FrameRateMode& mode) { DisplayEventReceiver::Event event; - event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, + event.header = {DisplayEventType::DISPLAY_EVENT_MODE_CHANGE, mode.modePtr->getPhysicalDisplayId(), systemTime()}; event.modeChange.modeId = ftl::to_underlying(mode.modePtr->getId()); event.modeChange.vsyncPeriod = mode.fps.getPeriodNsecs(); @@ -160,7 +167,7 @@ DisplayEventReceiver::Event makeFrameRateOverrideEvent(PhysicalDisplayId display return DisplayEventReceiver::Event{ .header = DisplayEventReceiver::Event::Header{ - .type = DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE, + .type = DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE, .displayId = displayId, .timestamp = systemTime(), }, @@ -171,7 +178,7 @@ DisplayEventReceiver::Event makeFrameRateOverrideEvent(PhysicalDisplayId display DisplayEventReceiver::Event makeFrameRateOverrideFlushEvent(PhysicalDisplayId displayId) { return DisplayEventReceiver::Event{ .header = DisplayEventReceiver::Event::Header{ - .type = DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH, + .type = DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH, .displayId = displayId, .timestamp = systemTime(), }}; @@ -182,7 +189,7 @@ DisplayEventReceiver::Event makeHdcpLevelsChange(PhysicalDisplayId displayId, return DisplayEventReceiver::Event{ .header = DisplayEventReceiver::Event::Header{ - .type = DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE, + .type = DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE, .displayId = displayId, .timestamp = systemTime(), }, @@ -195,7 +202,7 @@ DisplayEventReceiver::Event makeModeRejection(PhysicalDisplayId displayId, Displ return DisplayEventReceiver::Event{ .header = DisplayEventReceiver::Event::Header{ - .type = DisplayEventReceiver::DISPLAY_EVENT_MODE_REJECTION, + .type = DisplayEventType::DISPLAY_EVENT_MODE_REJECTION, .displayId = displayId, .timestamp = systemTime(), }, @@ -263,10 +270,10 @@ status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& eve return size < 0 ? status_t(size) : status_t(NO_ERROR); }; - if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE || - event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) { + if (event.header.type == DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE || + event.header.type == DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) { mPendingEvents.emplace_back(event); - if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) { + if (event.header.type == DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) { return status_t(NO_ERROR); } @@ -344,7 +351,8 @@ sp<EventThreadConnection> EventThread::createEventConnection( auto connection = sp<EventThreadConnection>::make(const_cast<EventThread*>(this), IPCThreadState::self()->getCallingUid(), eventRegistration); - if (FlagManager::getInstance().misc1()) { + if (FlagManager::getInstance().misc1() && + !FlagManager::getInstance().disable_sched_fifo_sf_sched()) { const int policy = SCHED_FIFO; connection->setMinSchedulerPolicy(policy, sched_get_priority_min(policy)); } @@ -523,7 +531,7 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { event = mPendingEvents.front(); mPendingEvents.pop_front(); - if (event->header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG) { + if (event->header.type == DisplayEventType::DISPLAY_EVENT_HOTPLUG) { if (event->hotplug.connectionError == 0) { if (event->hotplug.connected && !mVSyncState) { mVSyncState.emplace(); @@ -635,18 +643,21 @@ bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event, }; switch (event.header.type) { - case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: + case DisplayEventType::DISPLAY_EVENT_HOTPLUG: return true; - case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE: + case DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE: return true; - case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: { + case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE: { return connection->mEventRegistration.test( gui::ISurfaceComposer::EventRegistration::modeChanged); } - case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: + case DisplayEventType::DISPLAY_EVENT_MODE_REJECTION: + return true; + + case DisplayEventType::DISPLAY_EVENT_VSYNC: switch (connection->vsyncRequest) { case VSyncRequest::None: return false; @@ -672,13 +683,12 @@ bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event, return event.vsync.count % vsyncPeriod(connection->vsyncRequest) == 0; } - case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE: + case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE: [[fallthrough]]; - case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH: + case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH: return connection->mEventRegistration.test( gui::ISurfaceComposer::EventRegistration::frameRateOverride); - - default: + case DisplayEventType::DISPLAY_EVENT_NULL: return false; } } @@ -757,7 +767,7 @@ void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event, ftl::SmallVector<uid_t, 10> uidsPostedQueuedBuffers; for (const auto& consumer : consumers) { DisplayEventReceiver::Event copy = event; - if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { + if (event.header.type == DisplayEventType::DISPLAY_EVENT_VSYNC) { const Period frameInterval = mCallback.getVsyncPeriod(consumer->mOwnerUid); copy.vsync.vsyncData.frameInterval = frameInterval.ns(); generateFrameTimeline(copy.vsync.vsyncData, frameInterval.ns(), copy.header.timestamp, @@ -792,7 +802,7 @@ void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event, for (auto uid : uidsPostedQueuedBuffers) { mBufferStuffedUids.erase(uid); } - if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC && + if (event.header.type == DisplayEventType::DISPLAY_EVENT_VSYNC && FlagManager::getInstance().vrr_config()) { mLastCommittedVsyncTime = TimePoint::fromNs(event.vsync.vsyncData.preferredExpectedPresentationTime()); diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index 18bf41643c..a91dde7430 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -144,7 +144,7 @@ public: // An elevated number of queued buffers in the server is detected. This propagates a // flag to Choreographer indicating that buffer stuffing recovery should begin. - virtual void addBufferStuffedUids(BufferStuffingMap bufferStuffedUids); + virtual void addBufferStuffedUids(BufferStuffingMap bufferStuffedUids) = 0; }; struct IEventThreadCallback { diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp index 2e1f938126..91a798ed3e 100644 --- a/services/surfaceflinger/Scheduler/MessageQueue.cpp +++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp @@ -24,7 +24,7 @@ #include <scheduler/interface/ICompositor.h> #include "EventThread.h" -#include "FrameTimeline.h" +#include "FrameTimeline/FrameTimeline.h" #include "MessageQueue.h" namespace android::impl { diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index 4da76f6ecc..911d4894ce 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -554,8 +554,7 @@ void Scheduler::resyncAllToHardwareVsync(bool allowToEnable) { ftl::FakeGuard guard(kMainThreadContext); for (const auto& [id, display] : mDisplays) { - if (display.powerMode != hal::PowerMode::OFF || - !FlagManager::getInstance().multithreaded_present()) { + if (display.powerMode != hal::PowerMode::OFF) { resyncToHardwareVsyncLocked(id, allowToEnable); } } @@ -986,7 +985,7 @@ std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked( if (const auto pacesetterOpt = pacesetterDisplayLocked()) { const Display& pacesetter = *pacesetterOpt; - if (!FlagManager::getInstance().connected_display() || params.toggleIdleTimer) { + if (params.toggleIdleTimer) { pacesetter.selectorPtr->setIdleTimerCallbacks( {.platform = {.onReset = [this] { idleTimerCallback(TimerState::Reset); }, .onExpired = [this] { idleTimerCallback(TimerState::Expired); }}, @@ -1018,7 +1017,7 @@ void Scheduler::applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule> vsyncSchedu } void Scheduler::demotePacesetterDisplay(PromotionParams params) { - if (!FlagManager::getInstance().connected_display() || params.toggleIdleTimer) { + if (params.toggleIdleTimer) { // No need to lock for reads on kMainThreadContext. if (const auto pacesetterPtr = FTL_FAKE_GUARD(mDisplayLock, pacesetterSelectorPtrLocked())) { diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h index 3fdddac52a..81389e7362 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -386,7 +386,7 @@ private: // a deadlock where the main thread joins with the timer thread as the timer thread waits to // lock a mutex held by the main thread. struct PromotionParams { - // Whether to stop and start the idle timer. Ignored unless connected_display flag is set. + // Whether to stop and start the idle timer. bool toggleIdleTimer; }; diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp index ff360b754c..bb04d12d7c 100644 --- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp +++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp @@ -206,7 +206,12 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { // Normalizing to the oldest timestamp cuts down on error in calculating the intercept. const auto oldestTS = *std::min_element(mTimestamps.begin(), mTimestamps.end()); auto it = mRateMap.find(idealPeriod()); - auto const currentPeriod = it->second.slope; + // Calculated slope over the period of time can become outdated as the new timestamps are + // stored. Using idealPeriod instead provides a rate which is valid at all the times. + auto const currentPeriod = + mDisplayModePtr->getVrrConfig() && FlagManager::getInstance().vsync_predictor_recovery() + ? idealPeriod() + : it->second.slope; // The mean of the ordinals must be precise for the intercept calculation, so scale them up for // fixed-point arithmetic. diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameRateMode.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameRateMode.h index f2be316452..4dd3ab6a88 100644 --- a/services/surfaceflinger/Scheduler/include/scheduler/FrameRateMode.h +++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameRateMode.h @@ -33,6 +33,10 @@ struct FrameRateMode { } bool operator!=(const FrameRateMode& other) const { return !(*this == other); } + + bool matchesResolution(const FrameRateMode& other) const { + return modePtr->getResolution() == other.modePtr->getResolution(); + } }; inline std::string to_string(const FrameRateMode& mode) { diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h index 813d4dedff..ff461d2d85 100644 --- a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h +++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h @@ -24,6 +24,7 @@ #include <ui/DisplayId.h> #include <ui/Fence.h> #include <ui/FenceTime.h> +#include <ui/RingBuffer.h> #include <scheduler/Features.h> #include <scheduler/FrameTime.h> @@ -34,7 +35,6 @@ // TODO(b/185536303): Pull to FTL. #include "../../../TracedOrdinal.h" #include "../../../Utils/Dumper.h" -#include "../../../Utils/RingBuffer.h" namespace android::scheduler { @@ -108,7 +108,7 @@ protected: std::pair<bool /* wouldBackpressure */, PresentFence> expectedSignaledPresentFence( Period vsyncPeriod, Period minFramePeriod) const; std::array<PresentFence, 2> mPresentFencesLegacy; - utils::RingBuffer<PresentFence, 5> mPresentFences; + ui::RingBuffer<PresentFence, 5> mPresentFences; FrameTime mLastSignaledFrameTime; diff --git a/services/surfaceflinger/Scheduler/include/scheduler/interface/CompositionCoverage.h b/services/surfaceflinger/Scheduler/include/scheduler/interface/CompositionCoverage.h index 767462dfce..70ae940b65 100644 --- a/services/surfaceflinger/Scheduler/include/scheduler/interface/CompositionCoverage.h +++ b/services/surfaceflinger/Scheduler/include/scheduler/interface/CompositionCoverage.h @@ -36,7 +36,7 @@ enum class CompositionCoverage : std::uint8_t { using CompositionCoverageFlags = ftl::Flags<CompositionCoverage>; -using CompositionCoveragePerDisplay = ui::DisplayMap<DisplayId, CompositionCoverageFlags>; +using CompositionCoveragePerDisplay = ui::DisplayMap<DisplayIdVariant, CompositionCoverageFlags>; inline CompositionCoverageFlags multiDisplayUnion(const CompositionCoveragePerDisplay& displays) { CompositionCoverageFlags coverage; diff --git a/services/surfaceflinger/Scheduler/src/Timer.cpp b/services/surfaceflinger/Scheduler/src/Timer.cpp index 20c58eb52f..6a5eeba823 100644 --- a/services/surfaceflinger/Scheduler/src/Timer.cpp +++ b/services/surfaceflinger/Scheduler/src/Timer.cpp @@ -24,6 +24,7 @@ #include <sys/timerfd.h> #include <sys/unistd.h> +#include <common/FlagManager.h> #include <common/trace.h> #include <ftl/concat.h> #include <ftl/enum.h> @@ -155,8 +156,10 @@ bool Timer::dispatch() { setDebugState(DebugState::Running); struct sched_param param = {0}; param.sched_priority = 2; - if (pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m) != 0) { - ALOGW("Failed to set SCHED_FIFO on dispatch thread"); + if (!FlagManager::getInstance().disable_sched_fifo_sf_sched()) { + if (pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m) != 0) { + ALOGW("Failed to set SCHED_FIFO on dispatch thread"); + } } if (pthread_setname_np(pthread_self(), "TimerDispatch") != 0) { diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp index 41a9a1bb22..2906bbd5b8 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.cpp +++ b/services/surfaceflinger/ScreenCaptureOutput.cpp @@ -16,22 +16,29 @@ #include "ScreenCaptureOutput.h" #include "ScreenCaptureRenderSurface.h" +#include "common/include/common/FlagManager.h" #include "ui/Rotation.h" #include <compositionengine/CompositionEngine.h> #include <compositionengine/DisplayColorProfileCreationArgs.h> #include <compositionengine/impl/DisplayColorProfile.h> +#include <ui/HdrRenderTypeUtils.h> #include <ui/Rotation.h> namespace android { std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutputArgs args) { std::shared_ptr<ScreenCaptureOutput> output = compositionengine::impl::createOutputTemplated< - ScreenCaptureOutput, compositionengine::CompositionEngine, const RenderArea&, + ScreenCaptureOutput, compositionengine::CompositionEngine, + /* sourceCrop */ const Rect, ftl::Optional<DisplayIdVariant>, const compositionengine::Output::ColorProfile&, - bool>(args.compositionEngine, args.renderArea, args.colorProfile, args.regionSampling, - args.dimInGammaSpaceForEnhancedScreenshots, args.enableLocalTonemapping); - output->editState().isSecure = args.renderArea.isSecure(); + /* layerAlpha */ float, + /* regionSampling */ bool>(args.compositionEngine, args.sourceCrop, + args.displayIdVariant, args.colorProfile, args.layerAlpha, + args.regionSampling, + args.dimInGammaSpaceForEnhancedScreenshots, + args.enableLocalTonemapping); + output->editState().isSecure = args.isSecure; output->editState().isProtected = args.isProtected; output->setCompositionEnabled(true); output->setLayerFilter({args.layerStack}); @@ -45,16 +52,16 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp .setHasWideColorGamut(true) .Build())); - const Rect& sourceCrop = args.renderArea.getSourceCrop(); + const Rect& sourceCrop = args.sourceCrop; const ui::Rotation orientation = ui::ROTATION_0; output->setDisplaySize({sourceCrop.getWidth(), sourceCrop.getHeight()}); output->setProjection(orientation, sourceCrop, - {args.renderArea.getReqWidth(), args.renderArea.getReqHeight()}); + {args.reqBufferSize.width, args.reqBufferSize.height}); { std::string name = args.regionSampling ? "RegionSampling" : "ScreenCaptureOutput"; - if (auto displayDevice = args.renderArea.getDisplayDevice()) { - base::StringAppendF(&name, " for %" PRIu64, displayDevice->getId().value); + if (const auto id = args.displayIdVariant.and_then(asDisplayIdOfType<DisplayId>)) { + base::StringAppendF(&name, " for %" PRIu64, id->value); } output->setName(name); } @@ -62,11 +69,14 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp } ScreenCaptureOutput::ScreenCaptureOutput( - const RenderArea& renderArea, const compositionengine::Output::ColorProfile& colorProfile, + const Rect sourceCrop, ftl::Optional<DisplayIdVariant> displayIdVariant, + const compositionengine::Output::ColorProfile& colorProfile, float layerAlpha, bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots, bool enableLocalTonemapping) - : mRenderArea(renderArea), + : mSourceCrop(sourceCrop), + mDisplayIdVariant(displayIdVariant), mColorProfile(colorProfile), + mLayerAlpha(layerAlpha), mRegionSampling(regionSampling), mDimInGammaSpaceForEnhancedScreenshots(dimInGammaSpaceForEnhancedScreenshots), mEnableLocalTonemapping(enableLocalTonemapping) {} @@ -81,7 +91,7 @@ renderengine::DisplaySettings ScreenCaptureOutput::generateClientCompositionDisp const std::shared_ptr<renderengine::ExternalTexture>& buffer) const { auto clientCompositionDisplay = compositionengine::impl::Output::generateClientCompositionDisplaySettings(buffer); - clientCompositionDisplay.clip = mRenderArea.getSourceCrop(); + clientCompositionDisplay.clip = mSourceCrop; auto renderIntent = static_cast<ui::RenderIntent>(clientCompositionDisplay.renderIntent); if (mDimInGammaSpaceForEnhancedScreenshots && renderIntent != ui::RenderIntent::COLORIMETRIC && @@ -104,14 +114,81 @@ renderengine::DisplaySettings ScreenCaptureOutput::generateClientCompositionDisp return clientCompositionDisplay; } +std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> +ScreenCaptureOutput::generateLuts() { + std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> lutsMapper; + if (FlagManager::getInstance().luts_api()) { + std::vector<sp<GraphicBuffer>> buffers; + std::vector<int32_t> layerIds; + + for (const auto* layer : getOutputLayersOrderedByZ()) { + const auto& layerState = layer->getState(); + const auto* layerFEState = layer->getLayerFE().getCompositionState(); + auto pixelFormat = layerFEState->buffer + ? std::make_optional( + static_cast<ui::PixelFormat>(layerFEState->buffer->getPixelFormat())) + : std::nullopt; + const auto hdrType = getHdrRenderType(layerState.dataspace, pixelFormat, + layerFEState->desiredHdrSdrRatio); + if (layerFEState->buffer && !layerFEState->luts && + hdrType == HdrRenderType::GENERIC_HDR) { + buffers.push_back(layerFEState->buffer); + layerIds.push_back(layer->getLayerFE().getSequence()); + } + } + + std::vector<aidl::android::hardware::graphics::composer3::Luts> luts; + if (const auto physicalDisplayId = mDisplayIdVariant.and_then(asPhysicalDisplayId)) { + auto& hwc = getCompositionEngine().getHwComposer(); + hwc.getLuts(*physicalDisplayId, buffers, &luts); + } + + if (buffers.size() == luts.size()) { + for (size_t i = 0; i < luts.size(); i++) { + lutsMapper[layerIds[i]] = std::move(luts[i]); + } + } + } + return lutsMapper; +} + std::vector<compositionengine::LayerFE::LayerSettings> ScreenCaptureOutput::generateClientCompositionRequests( bool supportsProtectedContent, ui::Dataspace outputDataspace, std::vector<compositionengine::LayerFE*>& outLayerFEs) { + // This map maps the layer unique id to a Lut + std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> lutsMapper = + generateLuts(); + auto clientCompositionLayers = compositionengine::impl::Output:: generateClientCompositionRequests(supportsProtectedContent, outputDataspace, outLayerFEs); + for (auto& layer : clientCompositionLayers) { + if (lutsMapper.find(layer.sequence) != lutsMapper.end()) { + auto& aidlLuts = lutsMapper[layer.sequence]; + if (aidlLuts.pfd.get() >= 0 && aidlLuts.offsets) { + std::vector<int32_t> offsets = *aidlLuts.offsets; + std::vector<int32_t> dimensions; + dimensions.reserve(offsets.size()); + std::vector<int32_t> sizes; + sizes.reserve(offsets.size()); + std::vector<int32_t> keys; + keys.reserve(offsets.size()); + for (size_t j = 0; j < offsets.size(); j++) { + dimensions.emplace_back( + static_cast<int32_t>(aidlLuts.lutProperties[j].dimension)); + sizes.emplace_back(aidlLuts.lutProperties[j].size); + keys.emplace_back( + static_cast<int32_t>(aidlLuts.lutProperties[j].samplingKeys[0])); + } + layer.luts = std::make_shared<gui::DisplayLuts>(base::unique_fd( + aidlLuts.pfd.dup().get()), + offsets, dimensions, sizes, keys); + } + } + } + if (mRegionSampling) { for (auto& layer : clientCompositionLayers) { layer.backgroundBlurRadius = 0; @@ -129,14 +206,16 @@ ScreenCaptureOutput::generateClientCompositionRequests( } } - Rect sourceCrop = mRenderArea.getSourceCrop(); compositionengine::LayerFE::LayerSettings fillLayer; + fillLayer.name = "ScreenCaptureFillLayer"; fillLayer.source.buffer.buffer = nullptr; fillLayer.source.solidColor = half3(0.0f, 0.0f, 0.0f); fillLayer.geometry.boundaries = - FloatRect(static_cast<float>(sourceCrop.left), static_cast<float>(sourceCrop.top), - static_cast<float>(sourceCrop.right), static_cast<float>(sourceCrop.bottom)); - fillLayer.alpha = half(RenderArea::getCaptureFillValue(mRenderArea.getCaptureFill())); + FloatRect(static_cast<float>(mSourceCrop.left), static_cast<float>(mSourceCrop.top), + static_cast<float>(mSourceCrop.right), + static_cast<float>(mSourceCrop.bottom)); + + fillLayer.alpha = half(mLayerAlpha); clientCompositionLayers.insert(clientCompositionLayers.begin(), fillLayer); return clientCompositionLayers; diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h index c233ead575..d4e20fc2f3 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.h +++ b/services/surfaceflinger/ScreenCaptureOutput.h @@ -20,24 +20,27 @@ #include <compositionengine/RenderSurface.h> #include <compositionengine/impl/Output.h> #include <ui/Rect.h> - -#include "RenderArea.h" +#include <unordered_map> namespace android { struct ScreenCaptureOutputArgs { const compositionengine::CompositionEngine& compositionEngine; const compositionengine::Output::ColorProfile& colorProfile; - const RenderArea& renderArea; ui::LayerStack layerStack; + Rect sourceCrop; std::shared_ptr<renderengine::ExternalTexture> buffer; + ftl::Optional<DisplayIdVariant> displayIdVariant; + ui::Size reqBufferSize; float sdrWhitePointNits; float displayBrightnessNits; // Counterintuitively, when targetBrightness > 1.0 then dim the scene. float targetBrightness; + float layerAlpha; bool regionSampling; bool treat170mAsSrgb; bool dimInGammaSpaceForEnhancedScreenshots; + bool isSecure = false; bool isProtected = false; bool enableLocalTonemapping = false; }; @@ -48,10 +51,10 @@ struct ScreenCaptureOutputArgs { // SurfaceFlinger::captureLayers and SurfaceFlinger::captureDisplay. class ScreenCaptureOutput : public compositionengine::impl::Output { public: - ScreenCaptureOutput(const RenderArea& renderArea, + ScreenCaptureOutput(const Rect sourceCrop, ftl::Optional<DisplayIdVariant> displayIdVariant, const compositionengine::Output::ColorProfile& colorProfile, - bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots, - bool enableLocalTonemapping); + float layerAlpha, bool regionSampling, + bool dimInGammaSpaceForEnhancedScreenshots, bool enableLocalTonemapping); void updateColorProfile(const compositionengine::CompositionRefreshArgs&) override; @@ -65,8 +68,11 @@ protected: const std::shared_ptr<renderengine::ExternalTexture>& buffer) const override; private: - const RenderArea& mRenderArea; + std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> generateLuts(); + const Rect mSourceCrop; + const ftl::Optional<DisplayIdVariant> mDisplayIdVariant; const compositionengine::Output::ColorProfile& mColorProfile; + const float mLayerAlpha; const bool mRegionSampling; const bool mDimInGammaSpaceForEnhancedScreenshots; const bool mEnableLocalTonemapping; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index dd1119a5d1..73375250eb 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -44,6 +44,7 @@ #include <com_android_graphics_libgui_flags.h> #include <com_android_graphics_surfaceflinger_flags.h> #include <common/FlagManager.h> +#include <common/WorkloadTracer.h> #include <common/trace.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/CompositionRefreshArgs.h> @@ -134,10 +135,8 @@ #include "DisplayDevice.h" #include "DisplayHardware/ComposerHal.h" #include "DisplayHardware/FramebufferSurface.h" -#include "DisplayHardware/HWComposer.h" #include "DisplayHardware/Hal.h" #include "DisplayHardware/VirtualDisplaySurface.h" -#include "DisplayRenderArea.h" #include "Effects/Daltonizer.h" #include "FpsReporter.h" #include "FrameTimeline/FrameTimeline.h" @@ -151,13 +150,12 @@ #include "Jank/JankTracker.h" #include "Layer.h" #include "LayerProtoHelper.h" -#include "LayerRenderArea.h" #include "LayerVector.h" #include "MutexUtils.h" #include "NativeWindowSurface.h" #include "PowerAdvisor/PowerAdvisor.h" +#include "PowerAdvisor/Workload.h" #include "RegionSamplingThread.h" -#include "RenderAreaBuilder.h" #include "Scheduler/EventThread.h" #include "Scheduler/LayerHistory.h" #include "Scheduler/Scheduler.h" @@ -386,6 +384,7 @@ bool SurfaceFlinger::useHwcForRgbToYuv; bool SurfaceFlinger::hasSyncFramework; int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers; int64_t SurfaceFlinger::minAcquiredBuffers = 1; +std::optional<int64_t> SurfaceFlinger::maxAcquiredBuffersOpt; uint32_t SurfaceFlinger::maxGraphicsWidth; uint32_t SurfaceFlinger::maxGraphicsHeight; bool SurfaceFlinger::useContextPriority; @@ -454,6 +453,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2); minAcquiredBuffers = SurfaceFlingerProperties::min_acquired_buffers().value_or(minAcquiredBuffers); + maxAcquiredBuffersOpt = SurfaceFlingerProperties::max_acquired_buffers(); maxGraphicsWidth = std::max(max_graphics_width(0), 0); maxGraphicsHeight = std::max(max_graphics_height(0), 0); @@ -578,9 +578,10 @@ void SurfaceFlinger::run() { mScheduler->run(); } -sp<IBinder> SurfaceFlinger::createVirtualDisplay(const std::string& displayName, bool isSecure, - const std::string& uniqueId, - float requestedRefreshRate) { +sp<IBinder> SurfaceFlinger::createVirtualDisplay( + const std::string& displayName, bool isSecure, + gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy, const std::string& uniqueId, + float requestedRefreshRate) { // SurfaceComposerAIDL checks for some permissions, but adding an additional check here. // This is to ensure that only root, system, and graphics can request to create a secure // display. Secure displays can show secure content so we add an additional restriction on it. @@ -590,6 +591,8 @@ sp<IBinder> SurfaceFlinger::createVirtualDisplay(const std::string& displayName, return nullptr; } + ALOGD("Creating virtual display: %s", displayName.c_str()); + class DisplayToken : public BBinder { sp<SurfaceFlinger> flinger; virtual ~DisplayToken() { @@ -613,6 +616,9 @@ sp<IBinder> SurfaceFlinger::createVirtualDisplay(const std::string& displayName, // Set display as protected when marked as secure to ensure no behavior change // TODO (b/314820005): separate as a different arg when creating the display. state.isProtected = isSecure; + state.optimizationPolicy = optimizationPolicy; + // Virtual displays start in ON mode. + state.initialPowerMode = hal::PowerMode::ON; state.displayName = displayName; state.uniqueId = uniqueId; state.requestedRefreshRate = Fps::fromValue(requestedRefreshRate); @@ -634,6 +640,9 @@ status_t SurfaceFlinger::destroyVirtualDisplay(const sp<IBinder>& displayToken) ALOGE("%s: Invalid operation on physical display", __func__); return INVALID_OPERATION; } + + ALOGD("Destroying virtual display: %s", state.displayName.c_str()); + mCurrentState.displays.removeItemsAt(index); setTransactionFlags(eDisplayTransactionNeeded); return NO_ERROR; @@ -650,12 +659,14 @@ void SurfaceFlinger::enableHalVirtualDisplays(bool enable) { } } -VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution, ui::PixelFormat format, - const std::string& uniqueId) { +std::optional<VirtualDisplayIdVariant> SurfaceFlinger::acquireVirtualDisplay( + ui::Size resolution, ui::PixelFormat format, const std::string& uniqueId, + compositionengine::DisplayCreationArgsBuilder& builder) { if (auto& generator = mVirtualDisplayIdGenerators.hal) { if (const auto id = generator->generateId()) { if (getHwComposer().allocateVirtualDisplay(*id, resolution, &format)) { acquireVirtualDisplaySnapshot(*id, uniqueId); + builder.setId(*id); return *id; } @@ -670,22 +681,23 @@ VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution, ui:: const auto id = mVirtualDisplayIdGenerators.gpu.generateId(); LOG_ALWAYS_FATAL_IF(!id, "Failed to generate ID for GPU virtual display"); acquireVirtualDisplaySnapshot(*id, uniqueId); + builder.setId(*id); return *id; } -void SurfaceFlinger::releaseVirtualDisplay(VirtualDisplayId displayId) { - if (const auto id = HalVirtualDisplayId::tryCast(displayId)) { - if (auto& generator = mVirtualDisplayIdGenerators.hal) { - generator->releaseId(*id); - releaseVirtualDisplaySnapshot(*id); - } - return; - } - - const auto id = GpuVirtualDisplayId::tryCast(displayId); - LOG_ALWAYS_FATAL_IF(!id); - mVirtualDisplayIdGenerators.gpu.releaseId(*id); - releaseVirtualDisplaySnapshot(*id); +void SurfaceFlinger::releaseVirtualDisplay(VirtualDisplayIdVariant displayId) { + ftl::match( + displayId, + [this](HalVirtualDisplayId halVirtualDisplayId) { + if (auto& generator = mVirtualDisplayIdGenerators.hal) { + generator->releaseId(halVirtualDisplayId); + releaseVirtualDisplaySnapshot(halVirtualDisplayId); + } + }, + [this](GpuVirtualDisplayId gpuVirtualDisplayId) { + mVirtualDisplayIdGenerators.gpu.releaseId(gpuVirtualDisplayId); + releaseVirtualDisplaySnapshot(gpuVirtualDisplayId); + }); } void SurfaceFlinger::releaseVirtualDisplaySnapshot(VirtualDisplayId displayId) { @@ -879,6 +891,8 @@ renderengine::RenderEngine::BlurAlgorithm chooseBlurAlgorithm(bool supportsBlur) return renderengine::RenderEngine::BlurAlgorithm::GAUSSIAN; } else if (algorithm == "kawase2") { return renderengine::RenderEngine::BlurAlgorithm::KAWASE_DUAL_FILTER; + } else if (algorithm == "kawase") { + return renderengine::RenderEngine::BlurAlgorithm::KAWASE; } else { if (FlagManager::getInstance().window_blur_kawase2()) { return renderengine::RenderEngine::BlurAlgorithm::KAWASE_DUAL_FILTER; @@ -920,7 +934,8 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { mCompositionEngine->setTimeStats(mTimeStats); - mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName)); + mHWComposer = getFactory().createHWComposer(mHwcServiceName); + mCompositionEngine->setHwComposer(mHWComposer.get()); auto& composer = mCompositionEngine->getHwComposer(); composer.setCallback(*this); mDisplayModeController.setHwComposer(&composer); @@ -1008,9 +1023,8 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { mPowerAdvisor->init(); if (base::GetBoolProperty("service.sf.prime_shader_cache"s, true)) { - if (setSchedFifo(false) != NO_ERROR) { - ALOGW("Can't set SCHED_OTHER for primeCache"); - } + constexpr const char* kWhence = "primeCache"; + setSchedFifo(false, kWhence); mRenderEnginePrimeCacheFuture.callOnce([this] { renderengine::PrimeCacheConfig config; @@ -1046,9 +1060,7 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { return getRenderEngine().primeCache(config); }); - if (setSchedFifo(true) != NO_ERROR) { - ALOGW("Can't set SCHED_FIFO after primeCache"); - } + setSchedFifo(true, kWhence); } // Avoid blocking the main thread on `init` to set properties. @@ -1066,7 +1078,8 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { void SurfaceFlinger::initBootProperties() { property_set("service.sf.present_timestamp", mHasReliablePresentFences ? "1" : "0"); - if (base::GetBoolProperty("debug.sf.boot_animation"s, true)) { + if (base::GetBoolProperty("debug.sf.boot_animation"s, true) && + (base::GetIntProperty("debug.sf.nobootanimation"s, 0) == 0)) { // Reset and (if needed) start BootAnimation. property_set("service.bootanim.exit", "0"); property_set("service.bootanim.progress", "0"); @@ -1161,8 +1174,8 @@ status_t SurfaceFlinger::getStaticDisplayInfo(int64_t displayId, ui::StaticDispl } Mutex::Autolock lock(mStateLock); - const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId)); - const auto displayOpt = mPhysicalDisplays.get(*id).and_then(getDisplayDeviceAndSnapshot()); + const PhysicalDisplayId id = PhysicalDisplayId::fromValue(static_cast<uint64_t>(displayId)); + const auto displayOpt = mPhysicalDisplays.get(id).and_then(getDisplayDeviceAndSnapshot()); if (!displayOpt) { return NAME_NOT_FOUND; @@ -1172,6 +1185,7 @@ status_t SurfaceFlinger::getStaticDisplayInfo(int64_t displayId, ui::StaticDispl const auto& snapshot = snapshotRef.get(); info->connectionType = snapshot.connectionType(); + info->port = snapshot.port(); info->deviceProductInfo = snapshot.deviceProductInfo(); if (mEmulatedDisplayDensity) { @@ -1255,7 +1269,17 @@ void SurfaceFlinger::getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo*& info ui::FrameRateCategoryRate frameRateCategoryRate(normal.getValue(), high.getValue()); info->frameRateCategoryRate = frameRateCategoryRate; - info->supportedRefreshRates = display->refreshRateSelector().getSupportedFrameRates(); + if (info->hasArrSupport) { + info->supportedRefreshRates = display->refreshRateSelector().getSupportedFrameRates(); + } else { + // On non-ARR devices, list the refresh rates same as the supported display modes. + std::vector<float> supportedFrameRates; + supportedFrameRates.reserve(info->supportedDisplayModes.size()); + std::transform(info->supportedDisplayModes.begin(), info->supportedDisplayModes.end(), + std::back_inserter(supportedFrameRates), + [](ui::DisplayMode mode) { return mode.peakRefreshRate; }); + info->supportedRefreshRates = supportedFrameRates; + } info->activeColorMode = display->getCompositionDisplay()->getState().colorMode; info->hdrCapabilities = filterOut4k30(display->getHdrCapabilities()); @@ -1284,9 +1308,9 @@ status_t SurfaceFlinger::getDynamicDisplayInfoFromId(int64_t physicalDisplayId, Mutex::Autolock lock(mStateLock); - const auto id_ = - DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(physicalDisplayId)); - const auto displayOpt = mPhysicalDisplays.get(*id_).and_then(getDisplayDeviceAndSnapshot()); + const PhysicalDisplayId id = + PhysicalDisplayId::fromValue(static_cast<uint64_t>(physicalDisplayId)); + const auto displayOpt = mPhysicalDisplays.get(id).and_then(getDisplayDeviceAndSnapshot()); if (!displayOpt) { return NAME_NOT_FOUND; @@ -1361,7 +1385,8 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) { const auto selectorPtr = mDisplayModeController.selectorPtrFor(displayId); if (!selectorPtr) break; - const Fps renderRate = selectorPtr->getActiveMode().fps; + const auto activeMode = selectorPtr->getActiveMode(); + const Fps renderRate = activeMode.fps; // DisplayModeController::setDesiredMode updated the render rate, so inform Scheduler. mScheduler->setRenderRate(displayId, renderRate, true /* applyImmediately */); @@ -1380,6 +1405,15 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) { mScheduler->updatePhaseConfiguration(displayId, mode.fps); mScheduler->setModeChangePending(true); + + // The mode set to switch resolution is not initiated until the display transaction that + // resizes the display. DM sends this transaction in response to a mode change event, so + // emit the event now, not when finalizing the mode change as for a refresh rate switch. + if (FlagManager::getInstance().synced_resolution_switch() && + !mode.matchesResolution(activeMode)) { + mScheduler->onDisplayModeChanged(displayId, mode, + /*clearContentRequirements*/ true); + } break; } case DesiredModeAction::InitiateRenderRateSwitch: @@ -1458,19 +1492,25 @@ bool SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) { } const auto& activeMode = pendingModeOpt->mode; - - if (const auto oldResolution = - mDisplayModeController.getActiveMode(displayId).modePtr->getResolution(); - oldResolution != activeMode.modePtr->getResolution()) { - auto& state = mCurrentState.displays.editValueFor(getPhysicalDisplayTokenLocked(displayId)); - // We need to generate new sequenceId in order to recreate the display (and this - // way the framebuffer). - state.sequenceId = DisplayDeviceState{}.sequenceId; - state.physical->activeMode = activeMode.modePtr.get(); - processDisplayChangesLocked(); - - // The DisplayDevice has been destroyed, so abort the commit for the now dead FrameTargeter. - return false; + const bool resolutionMatch = !FlagManager::getInstance().synced_resolution_switch() || + activeMode.matchesResolution(mDisplayModeController.getActiveMode(displayId)); + + if (!FlagManager::getInstance().synced_resolution_switch()) { + if (const auto oldResolution = + mDisplayModeController.getActiveMode(displayId).modePtr->getResolution(); + oldResolution != activeMode.modePtr->getResolution()) { + auto& state = + mCurrentState.displays.editValueFor(getPhysicalDisplayTokenLocked(displayId)); + // We need to generate new sequenceId in order to recreate the display (and this + // way the framebuffer). + state.sequenceId = DisplayDeviceState{}.sequenceId; + state.physical->activeMode = activeMode.modePtr.get(); + processDisplayChangesLocked(); + + // The DisplayDevice has been destroyed, so abort the commit for the now dead + // FrameTargeter. + return false; + } } mDisplayModeController.finalizeModeChange(displayId, activeMode.modePtr->getId(), @@ -1478,7 +1518,8 @@ bool SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) { mScheduler->updatePhaseConfiguration(displayId, activeMode.fps); - if (pendingModeOpt->emitEvent) { + // Skip for resolution changes, since the event was already emitted on setting the desired mode. + if (resolutionMatch && pendingModeOpt->emitEvent) { mScheduler->onDisplayModeChanged(displayId, activeMode, /*clearContentRequirements*/ true); } @@ -1530,8 +1571,9 @@ void SurfaceFlinger::initiateDisplayModeChanges() { to_string(displayModePtrOpt->get()->getVsyncRate()).c_str(), to_string(displayId).c_str()); - if ((!FlagManager::getInstance().connected_display() || !desiredModeOpt->force) && - mDisplayModeController.getActiveMode(displayId) == desiredModeOpt->mode) { + const auto activeMode = mDisplayModeController.getActiveMode(displayId); + + if (!desiredModeOpt->force && desiredModeOpt->mode == activeMode) { applyActiveMode(displayId); continue; } @@ -1552,6 +1594,15 @@ void SurfaceFlinger::initiateDisplayModeChanges() { constraints.seamlessRequired = false; hal::VsyncPeriodChangeTimeline outTimeline; + // When initiating a resolution change, wait until the commit that resizes the display. + if (FlagManager::getInstance().synced_resolution_switch() && + !activeMode.matchesResolution(desiredModeOpt->mode)) { + const auto display = getDisplayDeviceLocked(displayId); + if (display->getSize() != desiredModeOpt->mode.modePtr->getResolution()) { + continue; + } + } + const auto error = mDisplayModeController.initiateModeChange(displayId, std::move(*desiredModeOpt), constraints, outTimeline); @@ -2257,8 +2308,7 @@ void SurfaceFlinger::scheduleSample() { void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp, std::optional<hal::VsyncPeriodNanos> vsyncPeriod) { - if (FlagManager::getInstance().connected_display() && timestamp < 0 && - vsyncPeriod.has_value()) { + if (timestamp < 0 && vsyncPeriod.has_value()) { if (mIsHdcpViaNegVsync && vsyncPeriod.value() == ~1) { const int32_t value = static_cast<int32_t>(-timestamp); // one byte is good enough to encode android.hardware.drm.HdcpLevel @@ -2287,12 +2337,12 @@ void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t t void SurfaceFlinger::onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId, DisplayHotplugEvent event) { if (event == DisplayHotplugEvent::CONNECTED || event == DisplayHotplugEvent::DISCONNECTED) { - hal::Connection connection = (event == DisplayHotplugEvent::CONNECTED) - ? hal::Connection::CONNECTED - : hal::Connection::DISCONNECTED; + const HWComposer::HotplugEvent hotplugEvent = event == DisplayHotplugEvent::CONNECTED + ? HWComposer::HotplugEvent::Connected + : HWComposer::HotplugEvent::Disconnected; { std::lock_guard<std::mutex> lock(mHotplugMutex); - mPendingHotplugEvents.push_back(HotplugEvent{hwcDisplayId, connection}); + mPendingHotplugEvents.push_back(HotplugEvent{hwcDisplayId, hotplugEvent}); } if (mScheduler) { @@ -2310,9 +2360,19 @@ void SurfaceFlinger::onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId, return; } - if (event == DisplayHotplugEvent::ERROR_LINK_UNSTABLE && - !FlagManager::getInstance().display_config_error_hal()) { - return; + if (event == DisplayHotplugEvent::ERROR_LINK_UNSTABLE) { + if (!FlagManager::getInstance().display_config_error_hal()) { + return; + } + { + std::lock_guard<std::mutex> lock(mHotplugMutex); + mPendingHotplugEvents.push_back( + HotplugEvent{hwcDisplayId, HWComposer::HotplugEvent::LinkUnstable}); + } + if (mScheduler) { + mScheduler->scheduleConfigure(); + } + // do not return to also report the error. } // TODO(b/311403559): use enum type instead of int @@ -2454,9 +2514,11 @@ void SurfaceFlinger::updateLayerHistory(nsecs_t now) { } bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, - bool flushTransactions, bool& outTransactionsAreEmpty) { + bool flushTransactions, bool& outTransactionsAreEmpty) + EXCLUDES(mStateLock) { using Changes = frontend::RequestedLayerState::Changes; SFTRACE_CALL(); + SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Transaction Handling"); frontend::Update update; if (flushTransactions) { SFTRACE_NAME("TransactionHandler:flushTransactions"); @@ -2483,8 +2545,20 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, mDestroyedHandles.clear(); } + size_t addedLayers = update.newLayers.size(); mLayerLifecycleManager.addLayers(std::move(update.newLayers)); update.transactions = mTransactionHandler.flushTransactions(); + ftl::Flags<adpf::Workload> committedWorkload; + for (auto& transaction : update.transactions) { + committedWorkload |= transaction.workloadHint; + } + SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME, + ftl::Concat("Layers: +", addedLayers, " -", + update.destroyedHandles.size(), + " txns:", update.transactions.size()) + .c_str()); + + mPowerAdvisor->setCommittedWorkload(committedWorkload); if (mTransactionTracing) { mTransactionTracing->addCommittedTransactions(ftl::to_underlying(vsyncId), frameTimeNs, update, mFrontEndDisplayInfos, @@ -2638,7 +2712,7 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, } bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId, - const scheduler::FrameTargets& frameTargets) { + const scheduler::FrameTargets& frameTargets) EXCLUDES(mStateLock) { const scheduler::FrameTarget& pacesetterFrameTarget = *frameTargets.get(pacesetterId)->get(); const VsyncId vsyncId = pacesetterFrameTarget.vsyncId(); @@ -2685,7 +2759,7 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId, return false; } } - + SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Commit"); const Period vsyncPeriod = mScheduler->getVsyncSchedule()->period(); // Save this once per commit + composite to ensure consistency @@ -2759,6 +2833,7 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId, // Hold mStateLock as chooseRefreshRateForContent promotes wp<Layer> to sp<Layer> // and may eventually call to ~Layer() if it holds the last reference { + SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Refresh Rate Selection"); bool updateAttachedChoreographer = mUpdateAttachedChoreographer; mUpdateAttachedChoreographer = false; @@ -2785,6 +2860,8 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId, CompositeResultsPerDisplay SurfaceFlinger::composite( PhysicalDisplayId pacesetterId, const scheduler::FrameTargeters& frameTargeters) { + SFTRACE_ASYNC_FOR_TRACK_BEGIN(WorkloadTracer::TRACK_NAME, "Composition", + WorkloadTracer::COMPOSITION_TRACE_COOKIE); const scheduler::FrameTarget& pacesetterTarget = frameTargeters.get(pacesetterId)->get()->target(); @@ -2800,9 +2877,9 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( // output. Layer stacks are not tracked in Display when we iterate through // frameTargeters. Cross-referencing layer stacks allows us to filter out displays // by ID with duplicate layer stacks before adding them to CompositionEngine output. - ui::DisplayMap<DisplayId, ui::LayerStack> physicalDisplayLayerStacks; + ui::DisplayMap<PhysicalDisplayId, ui::LayerStack> physicalDisplayLayerStacks; for (auto& [_, display] : displays) { - const auto id = PhysicalDisplayId::tryCast(display->getId()); + const auto id = asPhysicalDisplayId(display->getDisplayIdVariant()); if (id && frameTargeters.contains(*id)) { physicalDisplayLayerStacks.try_emplace(*id, display->getLayerStack()); } @@ -2810,18 +2887,20 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( // Tracks layer stacks of displays that are added to CompositionEngine output. ui::DisplayMap<ui::LayerStack, ftl::Unit> outputLayerStacks; - auto isOutputLayerStack = [&outputLayerStacks](DisplayId id, ui::LayerStack layerStack) { - if (FlagManager::getInstance().reject_dupe_layerstacks() && - outputLayerStacks.contains(layerStack)) { - // TODO: remove log and DisplayId from params once reject_dupe_layerstacks flag is - // removed - ALOGD("Existing layer stack ID %d output to another display %" PRIu64 - ", dropping display from outputs", - layerStack.id, id.value); - return true; + auto isUniqueOutputLayerStack = [&outputLayerStacks](DisplayId id, ui::LayerStack layerStack) { + if (FlagManager::getInstance().reject_dupe_layerstacks()) { + if (layerStack != ui::INVALID_LAYER_STACK && outputLayerStacks.contains(layerStack)) { + // TODO: remove log and DisplayId from params once reject_dupe_layerstacks flag is + // removed + ALOGD("Existing layer stack ID %d output to another display %" PRIu64 + ", dropping display from outputs", + layerStack.id, id.value); + return false; + } } + outputLayerStacks.try_emplace(layerStack); - return false; + return true; }; // Add outputs for physical displays. @@ -2830,7 +2909,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( if (const auto display = getCompositionDisplayLocked(id)) { const auto layerStack = physicalDisplayLayerStacks.get(id)->get(); - if (!isOutputLayerStack(display->getId(), layerStack)) { + if (isUniqueOutputLayerStack(display->getId(), layerStack)) { refreshArgs.outputs.push_back(display); } } @@ -2849,7 +2928,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( if (!refreshRate.isValid() || mScheduler->isVsyncInPhase(pacesetterTarget.frameBeginTime(), refreshRate)) { - if (!isOutputLayerStack(display->getId(), display->getLayerStack())) { + if (isUniqueOutputLayerStack(display->getId(), display->getLayerStack())) { refreshArgs.outputs.push_back(display->getCompositionDisplay()); } } @@ -2947,10 +3026,64 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( } mCompositionEngine->present(refreshArgs); - moveSnapshotsFromCompositionArgs(refreshArgs, layers); + ftl::Flags<adpf::Workload> compositedWorkload; + if (refreshArgs.updatingGeometryThisFrame || refreshArgs.updatingOutputGeometryThisFrame) { + compositedWorkload |= adpf::Workload::VISIBLE_REGION; + } + if (mFrontEndDisplayInfosChanged) { + compositedWorkload |= adpf::Workload::DISPLAY_CHANGES; + SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Display Changes"); + } + + int index = 0; + ftl::StaticVector<char, WorkloadTracer::COMPOSITION_SUMMARY_SIZE> compositionSummary; + auto lastLayerStack = ui::INVALID_LAYER_STACK; + uint64_t prevOverrideBufferId = 0; for (auto& [layer, layerFE] : layers) { CompositionResult compositionResult{layerFE->stealCompositionResult()}; + if (lastLayerStack != layerFE->mSnapshot->outputFilter.layerStack) { + if (lastLayerStack != ui::INVALID_LAYER_STACK) { + // add a space to separate displays + compositionSummary.push_back(' '); + } + lastLayerStack = layerFE->mSnapshot->outputFilter.layerStack; + } + + // If there are N layers in a cached set they should all share the same buffer id. + // The first layer in the cached set will be not skipped and layers 1..N-1 will be skipped. + // We expect all layers in the cached set to be marked as composited by HWC. + // Here is a made up example of how it is visualized + // + // [b:rrc][s:cc] + // + // This should be interpreted to mean that there are 2 cached sets. + // So there are only 2 non skipped layers -- b and s. + // The layers rrc and cc are flattened into layers b and s respectively. + const LayerFE::HwcLayerDebugState &hwcState = layerFE->getLastHwcState(); + if (hwcState.overrideBufferId != prevOverrideBufferId) { + // End the existing run. + if (prevOverrideBufferId) { + compositionSummary.push_back(']'); + } + // Start a new run. + if (hwcState.overrideBufferId) { + compositionSummary.push_back('['); + } + } + + compositionSummary.push_back( + layerFE->mSnapshot->classifyCompositionForDebug(hwcState)); + + if (hwcState.overrideBufferId && !hwcState.wasSkipped) { + compositionSummary.push_back(':'); + } + prevOverrideBufferId = hwcState.overrideBufferId; + + if (layerFE->mSnapshot->hasEffect()) { + compositedWorkload |= adpf::Workload::EFFECTS; + } + if (compositionResult.lastClientCompositionFence) { layer->setWasClientComposed(compositionResult.lastClientCompositionFence); } @@ -2958,7 +3091,26 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( mActivePictureTracker.onLayerComposed(*layer, *layerFE, compositionResult); } } + // End the last run. + if (prevOverrideBufferId) { + compositionSummary.push_back(']'); + } + // Concisely describe the layers composited this frame using single chars. GPU composited layers + // are uppercase, DPU composited are lowercase. Special chars denote effects (blur, shadow, + // etc.). This provides a snapshot of the compositing workload. + SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME, + ftl::Concat("Layers: ", layers.size(), " ", + ftl::truncated<WorkloadTracer::COMPOSITION_SUMMARY_SIZE>( + std::string_view(compositionSummary.begin(), + compositionSummary.size()))) + .c_str()); + + mPowerAdvisor->setCompositedWorkload(compositedWorkload); + moveSnapshotsFromCompositionArgs(refreshArgs, layers); + SFTRACE_ASYNC_FOR_TRACK_END(WorkloadTracer::TRACK_NAME, + WorkloadTracer::COMPOSITION_TRACE_COOKIE); + SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Post Composition"); SFTRACE_NAME("postComposition"); mTimeStats->recordFrameDuration(pacesetterTarget.frameBeginTime().ns(), systemTime()); @@ -2993,7 +3145,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( for (const auto& [_, display] : displays) { const auto& state = display->getCompositionDisplay()->getState(); CompositionCoverageFlags& flags = - mCompositionCoverage.try_emplace(display->getId()).first->second; + mCompositionCoverage.try_emplace(display->getDisplayIdVariant()).first->second; if (state.usesDeviceComposition) { flags |= CompositionCoverage::Hwc; @@ -3047,8 +3199,8 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( CompositeResultsPerDisplay resultsPerDisplay; // Filter out virtual displays. - for (const auto& [id, coverage] : mCompositionCoverage) { - if (const auto idOpt = PhysicalDisplayId::tryCast(id)) { + for (const auto& [idVar, coverage] : mCompositionCoverage) { + if (const auto idOpt = asPhysicalDisplayId(idVar)) { resultsPerDisplay.try_emplace(*idOpt, CompositeResult{coverage}); } } @@ -3086,16 +3238,12 @@ bool SurfaceFlinger::isHdrLayer(const frontend::LayerSnapshot& snapshot) const { return false; } -ui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(DisplayId displayId, +ui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(PhysicalDisplayId displayId, bool isPrimary) const { - const auto id = PhysicalDisplayId::tryCast(displayId); - if (!id) { - return ui::ROTATION_0; - } if (!mIgnoreHwcPhysicalDisplayOrientation && getHwComposer().getComposer()->isSupported( Hwc2::Composer::OptionalFeature::PhysicalDisplayOrientation)) { - switch (getHwComposer().getPhysicalDisplayOrientation(*id)) { + switch (getHwComposer().getPhysicalDisplayOrientation(displayId)) { case Hwc2::AidlTransform::ROT_90: return ui::ROTATION_90; case Hwc2::AidlTransform::ROT_180: @@ -3212,12 +3360,12 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, const auto schedule = mScheduler->getVsyncSchedule(); const TimePoint vsyncDeadline = schedule->vsyncDeadlineAfter(presentTime); - const Period vsyncPeriod = schedule->period(); + const Fps renderRate = pacesetterDisplay->refreshRateSelector().getActiveMode().fps; const nsecs_t vsyncPhase = mScheduler->getVsyncConfiguration().getCurrentConfigs().late.sfOffset; - const CompositorTiming compositorTiming(vsyncDeadline.ns(), vsyncPeriod.ns(), vsyncPhase, - presentLatency.ns()); + const CompositorTiming compositorTiming(vsyncDeadline.ns(), renderRate.getPeriodNsecs(), + vsyncPhase, presentLatency.ns()); ui::DisplayMap<ui::LayerStack, const DisplayDevice*> layerStackToDisplay; { @@ -3368,13 +3516,7 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, mTimeStats->setPresentFenceGlobal(pacesetterPresentFenceTime); for (auto&& [id, presentFence] : presentFences) { - ftl::FakeGuard guard(mStateLock); - const bool isInternalDisplay = - mPhysicalDisplays.get(id).transform(&PhysicalDisplay::isInternal).value_or(false); - - if (isInternalDisplay) { - mScheduler->addPresentFence(id, std::move(presentFence)); - } + mScheduler->addPresentFence(id, std::move(presentFence)); } const bool hasPacesetterDisplay = @@ -3439,9 +3581,8 @@ std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes( std::vector<HWComposer::HWCDisplayMode> hwcModes; std::optional<hal::HWConfigId> activeModeHwcIdOpt; - const bool isExternalDisplay = FlagManager::getInstance().connected_display() && - getHwComposer().getDisplayConnectionType(displayId) == - ui::DisplayConnectionType::External; + const bool isExternalDisplay = getHwComposer().getDisplayConnectionType(displayId) == + ui::DisplayConnectionType::External; int attempt = 0; constexpr int kMaxAttempts = 3; @@ -3599,16 +3740,17 @@ bool SurfaceFlinger::configureLocked() { events = std::move(mPendingHotplugEvents); } - for (const auto [hwcDisplayId, connection] : events) { - if (auto info = getHwComposer().onHotplug(hwcDisplayId, connection)) { + for (const auto [hwcDisplayId, event] : events) { + if (auto info = getHwComposer().onHotplug(hwcDisplayId, event)) { const auto displayId = info->id; const ftl::Concat displayString("display ", displayId.value, "(HAL ID ", hwcDisplayId, ')'); - - if (connection == hal::Connection::CONNECTED) { + // TODO: b/393126541 - replace if with switch as all cases are handled. + if (event == HWComposer::HotplugEvent::Connected || + event == HWComposer::HotplugEvent::LinkUnstable) { const auto activeModeIdOpt = processHotplugConnect(displayId, hwcDisplayId, std::move(*info), - displayString.c_str()); + displayString.c_str(), event); if (!activeModeIdOpt) { mScheduler->dispatchHotplugError( static_cast<int32_t>(DisplayHotplugEvent::ERROR_UNKNOWN)); @@ -3634,7 +3776,7 @@ bool SurfaceFlinger::configureLocked() { LOG_ALWAYS_FATAL_IF(!snapshotOpt); mDisplayModeController.registerDisplay(*snapshotOpt, *activeModeIdOpt, config); - } else { + } else { // event == HWComposer::HotplugEvent::Disconnected // Unregister before destroying the DisplaySnapshot below. mDisplayModeController.unregisterDisplay(displayId); @@ -3649,7 +3791,8 @@ bool SurfaceFlinger::configureLocked() { std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDisplayId displayId, hal::HWDisplayId hwcDisplayId, DisplayIdentificationInfo&& info, - const char* displayString) { + const char* displayString, + HWComposer::HotplugEvent event) { auto [displayModes, activeMode] = loadDisplayModes(displayId); if (!activeMode) { ALOGE("Failed to hotplug %s", displayString); @@ -3662,6 +3805,7 @@ std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDispl if (const auto displayOpt = mPhysicalDisplays.get(displayId)) { const auto& display = displayOpt->get(); const auto& snapshot = display.snapshot(); + const uint8_t port = snapshot.port(); std::optional<DeviceProductInfo> deviceProductInfo; if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) { @@ -3673,16 +3817,19 @@ std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDispl // Use the cached port via snapshot because we are updating an existing // display on reconnect. const auto it = - mPhysicalDisplays.try_replace(displayId, display.token(), displayId, - snapshot.port(), snapshot.connectionType(), - std::move(displayModes), std::move(colorModes), - std::move(deviceProductInfo)); + mPhysicalDisplays.try_replace(displayId, display.token(), displayId, port, + snapshot.connectionType(), std::move(displayModes), + std::move(colorModes), std::move(deviceProductInfo)); auto& state = mCurrentState.displays.editValueFor(it->second.token()); state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId. state.physical->activeMode = std::move(activeMode); + state.physical->port = port; ALOGI("Reconnecting %s", displayString); return activeModeId; + } else if (event == HWComposer::HotplugEvent::LinkUnstable) { + ALOGE("Failed to reconnect unknown %s", displayString); + return std::nullopt; } const sp<IBinder> token = sp<BBinder>::make(); @@ -3696,6 +3843,7 @@ std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDispl DisplayDeviceState state; state.physical = {.id = displayId, .hwcDisplayId = hwcDisplayId, + .port = info.port, .activeMode = std::move(activeMode)}; if (mIsHdcpViaNegVsync) { state.isSecure = connectionType == ui::DisplayConnectionType::Internal; @@ -3743,13 +3891,17 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( creationArgs.hasWideColorGamut = false; creationArgs.supportedPerFrameMetadata = 0; - if (const auto physicalIdOpt = PhysicalDisplayId::tryCast(compositionDisplay->getId())) { + if (const auto physicalIdOpt = + compositionDisplay->getDisplayIdVariant().and_then(asPhysicalDisplayId)) { const auto physicalId = *physicalIdOpt; creationArgs.isPrimary = physicalId == getPrimaryDisplayIdLocked(); creationArgs.refreshRateSelector = FTL_FAKE_GUARD(kMainThreadContext, mDisplayModeController.selectorPtrFor(physicalId)); + creationArgs.physicalOrientation = + getPhysicalDisplayOrientation(physicalId, creationArgs.isPrimary); + ALOGV("Display Orientation: %s", toCString(creationArgs.physicalOrientation)); mPhysicalDisplays.get(physicalId) .transform(&PhysicalDisplay::snapshotRef) @@ -3762,7 +3914,8 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( })); } - if (const auto id = HalDisplayId::tryCast(compositionDisplay->getId())) { + if (const auto id = compositionDisplay->getDisplayIdVariant().and_then( + asHalDisplayId<DisplayIdVariant>)) { getHwComposer().getHdrCapabilities(*id, &creationArgs.hdrCapabilities); creationArgs.supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(*id); } @@ -3778,11 +3931,12 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( nativeWindow->setSwapInterval(nativeWindow.get(), 0); } - creationArgs.physicalOrientation = - getPhysicalDisplayOrientation(compositionDisplay->getId(), creationArgs.isPrimary); - ALOGV("Display Orientation: %s", toCString(creationArgs.physicalOrientation)); - - creationArgs.initialPowerMode = state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF; + if (FlagManager::getInstance().correct_virtual_display_power_state()) { + creationArgs.initialPowerMode = state.initialPowerMode; + } else { + creationArgs.initialPowerMode = + state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF; + } creationArgs.requestedRefreshRate = state.requestedRefreshRate; @@ -3806,10 +3960,12 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( mode.getPeakFps()); } - display->setLayerFilter(makeLayerFilterForDisplay(display->getId(), state.layerStack)); + display->setLayerFilter( + makeLayerFilterForDisplay(display->getDisplayIdVariant(), state.layerStack)); display->setProjection(state.orientation, state.layerStackSpaceRect, state.orientedDisplaySpaceRect); display->setDisplayName(state.displayName); + display->setOptimizationPolicy(state.optimizationPolicy); display->setFlags(state.flags); return display; @@ -3855,14 +4011,18 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, // Virtual displays without a surface are dormant: // they have external state (layer stack, projection, // etc.) but no internal state (i.e. a DisplayDevice). + ALOGD("Not adding dormant virtual display with token %p: %s", displayToken.unsafe_get(), + state.displayName.c_str()); return; } compositionengine::DisplayCreationArgsBuilder builder; + std::optional<VirtualDisplayIdVariant> virtualDisplayIdVariantOpt; if (const auto& physical = state.physical) { builder.setId(physical->id); } else { - builder.setId(acquireVirtualDisplay(resolution, pixelFormat, state.uniqueId)); + virtualDisplayIdVariantOpt = + acquireVirtualDisplay(resolution, pixelFormat, state.uniqueId, builder); } builder.setPixels(resolution); @@ -3882,10 +4042,10 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false); if (state.isVirtual()) { - const auto displayId = VirtualDisplayId::tryCast(compositionDisplay->getId()); - LOG_FATAL_IF(!displayId); - auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *displayId, state.surface, - bqProducer, bqConsumer, state.displayName); + LOG_FATAL_IF(!virtualDisplayIdVariantOpt); + auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *virtualDisplayIdVariantOpt, + state.surface, bqProducer, bqConsumer, + state.displayName); displaySurface = surface; producer = std::move(surface); } else { @@ -3893,18 +4053,17 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, "adding a supported display, but rendering " "surface is provided (%p), ignoring it", state.surface.get()); - const auto displayId = PhysicalDisplayId::tryCast(compositionDisplay->getId()); - LOG_FATAL_IF(!displayId); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) const auto frameBufferSurface = - sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqProducer, bqConsumer, + sp<FramebufferSurface>::make(getHwComposer(), state.physical->id, bqProducer, + bqConsumer, state.physical->activeMode->getResolution(), ui::Size(maxGraphicsWidth, maxGraphicsHeight)); displaySurface = frameBufferSurface; producer = frameBufferSurface->getSurface()->getIGraphicBufferProducer(); #else displaySurface = - sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqConsumer, + sp<FramebufferSurface>::make(getHwComposer(), state.physical->id, bqConsumer, state.physical->activeMode->getResolution(), ui::Size(maxGraphicsWidth, maxGraphicsHeight)); producer = bqProducer; @@ -3916,9 +4075,6 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, displaySurface, producer); if (mScheduler && !display->isVirtual()) { - // TODO(b/241285876): Annotate `processDisplayAdded` instead. - ftl::FakeGuard guard(kMainThreadContext); - // For hotplug reconnect, renew the registration since display modes have been reloaded. mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(), mActiveDisplayId); @@ -3932,13 +4088,16 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, incRefreshableDisplays(); } + if (FlagManager::getInstance().correct_virtual_display_power_state()) { + applyOptimizationPolicy(__func__); + } + mDisplays.try_emplace(displayToken, std::move(display)); // For an external display, loadDisplayModes already attempted to select the same mode // as DM, but SF still needs to be updated to match. // TODO (b/318534874): Let DM decide the initial mode. - if (const auto& physical = state.physical; - mScheduler && physical && FlagManager::getInstance().connected_display()) { + if (const auto& physical = state.physical; mScheduler && physical) { const bool isInternalDisplay = mPhysicalDisplays.get(physical->id) .transform(&PhysicalDisplay::isInternal) .value_or(false); @@ -3961,8 +4120,8 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) { if (display) { display->disconnect(); - if (display->isVirtual()) { - releaseVirtualDisplay(display->getVirtualId()); + if (const auto virtualDisplayIdVariant = display->getVirtualDisplayIdVariant()) { + releaseVirtualDisplay(*virtualDisplayIdVariant); } else { mScheduler->unregisterDisplay(display->getPhysicalId(), mActiveDisplayId); } @@ -3989,6 +4148,10 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) { // not be accessible. })); } + + if (FlagManager::getInstance().correct_virtual_display_power_state()) { + applyOptimizationPolicy(__func__); + } } void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, @@ -4001,8 +4164,8 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, if (currentBinder != drawingBinder || currentState.sequenceId != drawingState.sequenceId) { if (const auto display = getDisplayDeviceLocked(displayToken)) { display->disconnect(); - if (display->isVirtual()) { - releaseVirtualDisplay(display->getVirtualId()); + if (const auto virtualDisplayIdVariant = display->getVirtualDisplayIdVariant()) { + releaseVirtualDisplay(*virtualDisplayIdVariant); } if (display->isRefreshable()) { @@ -4014,7 +4177,7 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, if (const auto& physical = currentState.physical) { getHwComposer().allocatePhysicalDisplay(physical->hwcDisplayId, physical->id, - /*physicalSize=*/std::nullopt); + physical->port, /*physicalSize=*/std::nullopt); } processDisplayAdded(displayToken, currentState); @@ -4022,7 +4185,7 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, if (currentState.physical) { const auto display = getDisplayDeviceLocked(displayToken); if (!mSkipPowerOnForQuiescent) { - setPowerModeInternal(display, hal::PowerMode::ON); + setPhysicalDisplayPowerMode(display, hal::PowerMode::ON); } if (display->getPhysicalId() == mActiveDisplayId) { @@ -4034,12 +4197,41 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, if (const auto display = getDisplayDeviceLocked(displayToken)) { if (currentState.layerStack != drawingState.layerStack) { - display->setLayerFilter( - makeLayerFilterForDisplay(display->getId(), currentState.layerStack)); + display->setLayerFilter(makeLayerFilterForDisplay(display->getDisplayIdVariant(), + currentState.layerStack)); } if (currentState.flags != drawingState.flags) { display->setFlags(currentState.flags); } + + const auto updateDisplaySize = [&]() { + if (currentState.width != drawingState.width || + currentState.height != drawingState.height) { + const ui::Size resolution = ui::Size(currentState.width, currentState.height); + + // Resize the framebuffer. For a virtual display, always do so. For a physical + // display, only do so if it has a pending modeset for the matching resolution. + if (!currentState.physical || + (FlagManager::getInstance().synced_resolution_switch() && + mDisplayModeController.getDesiredMode(display->getPhysicalId()) + .transform([resolution](const auto& request) { + return resolution == request.mode.modePtr->getResolution(); + }) + .value_or(false))) { + display->setDisplaySize(resolution); + } + + if (display->getId() == mActiveDisplayId) { + onActiveDisplaySizeChanged(*display); + } + } + }; + + if (FlagManager::getInstance().synced_resolution_switch()) { + // Update display size first, as display projection below depends on it. + updateDisplaySize(); + } + if ((currentState.orientation != drawingState.orientation) || (currentState.layerStackSpaceRect != drawingState.layerStackSpaceRect) || (currentState.orientedDisplaySpaceRect != drawingState.orientedDisplaySpaceRect)) { @@ -4051,13 +4243,9 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, ui::Transform::toRotationFlags(display->getOrientation()); } } - if (currentState.width != drawingState.width || - currentState.height != drawingState.height) { - display->setDisplaySize(currentState.width, currentState.height); - if (display->getId() == mActiveDisplayId) { - onActiveDisplaySizeChanged(*display); - } + if (!FlagManager::getInstance().synced_resolution_switch()) { + updateDisplaySize(); } } } @@ -4181,20 +4369,19 @@ void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) { std::move(displayInfos), ftl::to_underlying(vsyncId), frameTime.ns()}, - std::move( - inputWindowCommands.windowInfosReportedListeners), + std::move(inputWindowCommands.releaseListeners()), /* forceImmediateCall= */ visibleWindowsChanged || - !inputWindowCommands.focusRequests.empty()); + !inputWindowCommands.getFocusRequests().empty()); } else { // If there are listeners but no changes to input windows, call the listeners // immediately. - for (const auto& listener : inputWindowCommands.windowInfosReportedListeners) { + for (const auto& listener : inputWindowCommands.getListeners()) { if (IInterface::asBinder(listener)->isBinderAlive()) { listener->onWindowInfosReported(); } } } - for (const auto& focusRequest : inputWindowCommands.focusRequests) { + for (const auto& focusRequest : inputWindowCommands.getFocusRequests()) { inputFlinger->setFocusedWindow(focusRequest); } }}); @@ -4253,7 +4440,7 @@ void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos, void SurfaceFlinger::updateCursorAsync() { compositionengine::CompositionRefreshArgs refreshArgs; for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) { - if (HalDisplayId::tryCast(display->getId())) { + if (asHalDisplayId(display->getDisplayIdVariant())) { refreshArgs.outputs.push_back(display->getCompositionDisplay()); } } @@ -4549,27 +4736,6 @@ void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, co status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle, const sp<Layer>& layer, const wp<Layer>& parent, uint32_t* outTransformHint) { - if (mNumLayers >= MAX_LAYERS) { - static std::atomic<nsecs_t> lasttime{0}; - nsecs_t now = systemTime(); - if (lasttime != 0 && ns2s(now - lasttime.load()) < 10) { - ALOGE("AddClientLayer already dumped 10s before"); - return NO_MEMORY; - } else { - lasttime = now; - } - - ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(), - MAX_LAYERS); - static_cast<void>(mScheduler->schedule([&]() FTL_FAKE_GUARD(kMainThreadContext) { - ALOGE("Dumping on-screen layers."); - mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getHierarchy()); - ALOGE("Dumping off-screen layers."); - mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getOffscreenHierarchy()); - })); - return NO_MEMORY; - } - if (outTransformHint) { *outTransformHint = mActiveDisplayTransformHint; } @@ -4778,12 +4944,14 @@ bool SurfaceFlinger::flushTransactionQueues() { return applyTransactions(transactions); } -bool SurfaceFlinger::applyTransactions(std::vector<QueuedTransactionState>& transactions) { +bool SurfaceFlinger::applyTransactions(std::vector<QueuedTransactionState>& transactions) + EXCLUDES(mStateLock) { Mutex::Autolock lock(mStateLock); return applyTransactionsLocked(transactions); } -bool SurfaceFlinger::applyTransactionsLocked(std::vector<QueuedTransactionState>& transactions) { +bool SurfaceFlinger::applyTransactionsLocked(std::vector<QueuedTransactionState>& transactions) + REQUIRES(mStateLock) { bool needsTraversal = false; // Now apply all transactions. for (auto& transaction : transactions) { @@ -4860,49 +5028,54 @@ bool SurfaceFlinger::shouldLatchUnsignaled(const layer_state_t& state, size_t nu return true; } -status_t SurfaceFlinger::setTransactionState( - const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states, - Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, - const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, - const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId, - const std::vector<uint64_t>& mergedTransactionIds) { +status_t SurfaceFlinger::setTransactionState(TransactionState&& transactionState) { SFTRACE_CALL(); IPCThreadState* ipc = IPCThreadState::self(); const int originPid = ipc->getCallingPid(); const int originUid = ipc->getCallingUid(); uint32_t permissions = LayerStatePermissions::getTransactionPermissions(originPid, originUid); - for (auto& composerState : states) { + ftl::Flags<adpf::Workload> queuedWorkload; + for (auto& composerState : transactionState.mComposerStates) { composerState.state.sanitize(permissions); + if (composerState.state.what & layer_state_t::COMPOSITION_EFFECTS) { + queuedWorkload |= adpf::Workload::EFFECTS; + } + if (composerState.state.what & layer_state_t::VISIBLE_REGION_CHANGES) { + queuedWorkload |= adpf::Workload::VISIBLE_REGION; + } } - for (DisplayState& display : displays) { + for (DisplayState& display : transactionState.mDisplayStates) { display.sanitize(permissions); } - if (!inputWindowCommands.empty() && + if (!transactionState.mInputWindowCommands.empty() && (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) { ALOGE("Only privileged callers are allowed to send input commands."); - inputWindowCommands.clear(); + transactionState.mInputWindowCommands.clear(); } - if (flags & (eEarlyWakeupStart | eEarlyWakeupEnd)) { + if (transactionState.mFlags & (eEarlyWakeupStart | eEarlyWakeupEnd)) { const bool hasPermission = (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) || callingThreadHasPermission(sWakeupSurfaceFlinger); if (!hasPermission) { ALOGE("Caller needs permission android.permission.WAKEUP_SURFACE_FLINGER to use " "eEarlyWakeup[Start|End] flags"); - flags &= ~(eEarlyWakeupStart | eEarlyWakeupEnd); + transactionState.mFlags &= ~(eEarlyWakeupStart | eEarlyWakeupEnd); } } + if (transactionState.mFlags & eEarlyWakeupStart) { + queuedWorkload |= adpf::Workload::WAKEUP; + } + mPowerAdvisor->setQueuedWorkload(queuedWorkload); const int64_t postTime = systemTime(); std::vector<uint64_t> uncacheBufferIds; - uncacheBufferIds.reserve(uncacheBuffers.size()); - for (const auto& uncacheBuffer : uncacheBuffers) { + uncacheBufferIds.reserve(transactionState.mUncacheBuffers.size()); + for (const auto& uncacheBuffer : transactionState.mUncacheBuffers) { sp<GraphicBuffer> buffer = ClientCache::getInstance().erase(uncacheBuffer); if (buffer != nullptr) { uncacheBufferIds.push_back(buffer->getId()); @@ -4910,8 +5083,8 @@ status_t SurfaceFlinger::setTransactionState( } std::vector<ResolvedComposerState> resolvedStates; - resolvedStates.reserve(states.size()); - for (auto& state : states) { + resolvedStates.reserve(transactionState.mComposerStates.size()); + for (auto& state : transactionState.mComposerStates) { resolvedStates.emplace_back(std::move(state)); auto& resolvedState = resolvedStates.back(); resolvedState.layerId = LayerHandle::getLayerId(resolvedState.state.surface); @@ -4922,44 +5095,35 @@ status_t SurfaceFlinger::setTransactionState( layer->getDebugName() : std::to_string(resolvedState.state.layerId); resolvedState.externalTexture = getExternalTextureFromBufferData(*resolvedState.state.bufferData, - layerName.c_str(), transactionId); + layerName.c_str(), transactionState.getId()); if (resolvedState.externalTexture) { resolvedState.state.bufferData->buffer = resolvedState.externalTexture->getBuffer(); } mBufferCountTracker.increment(resolvedState.layerId); } if (resolvedState.state.what & layer_state_t::eReparent) { - resolvedState.parentId = - getLayerIdFromSurfaceControl(resolvedState.state.parentSurfaceControlForChild); + resolvedState.parentId = getLayerIdFromSurfaceControl( + resolvedState.state.getParentSurfaceControlForChild()); } if (resolvedState.state.what & layer_state_t::eRelativeLayerChanged) { - resolvedState.relativeParentId = - getLayerIdFromSurfaceControl(resolvedState.state.relativeLayerSurfaceControl); + resolvedState.relativeParentId = getLayerIdFromSurfaceControl( + resolvedState.state.getRelativeLayerSurfaceControl()); } if (resolvedState.state.what & layer_state_t::eInputInfoChanged) { wp<IBinder>& touchableRegionCropHandle = - resolvedState.state.windowInfoHandle->editInfo()->touchableRegionCropHandle; + resolvedState.state.editWindowInfo()->touchableRegionCropHandle; resolvedState.touchCropId = LayerHandle::getLayerId(touchableRegionCropHandle.promote()); } } - QueuedTransactionState state{frameTimelineInfo, - resolvedStates, - displays, - flags, - applyToken, - std::move(inputWindowCommands), - desiredPresentTime, - isAutoTimestamp, + QueuedTransactionState state{std::move(transactionState), + std::move(resolvedStates), std::move(uncacheBufferIds), postTime, - hasListenerCallbacks, - listenerCallbacks, originPid, - originUid, - transactionId, - mergedTransactionIds}; + originUid}; + state.workloadHint = queuedWorkload; if (mTransactionTracing) { mTransactionTracing->addQueuedTransaction(state); @@ -4981,22 +5145,20 @@ status_t SurfaceFlinger::setTransactionState( for (const auto& [displayId, data] : mNotifyExpectedPresentMap) { if (data.hintStatus.load() == NotifyExpectedPresentHintStatus::ScheduleOnTx) { - scheduleNotifyExpectedPresentHint(displayId, VsyncId{frameTimelineInfo.vsyncId}); + scheduleNotifyExpectedPresentHint(displayId, VsyncId{state.frameTimelineInfo.vsyncId}); } } - setTransactionFlags(eTransactionFlushNeeded, schedule, applyToken, frameHint); + setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken, frameHint); return NO_ERROR; } -bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelineInfo, - std::vector<ResolvedComposerState>& states, - Vector<DisplayState>& displays, uint32_t flags, - const InputWindowCommands& inputWindowCommands, - const int64_t desiredPresentTime, bool isAutoTimestamp, - const std::vector<uint64_t>& uncacheBufferIds, - const int64_t postTime, bool hasListenerCallbacks, - const std::vector<ListenerCallbacks>& listenerCallbacks, - int originPid, int originUid, uint64_t transactionId) { +bool SurfaceFlinger::applyTransactionState( + const FrameTimelineInfo& frameTimelineInfo, std::vector<ResolvedComposerState>& states, + std::span<DisplayState> displays, uint32_t flags, + const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, + bool isAutoTimestamp, const std::vector<uint64_t>& uncacheBufferIds, const int64_t postTime, + bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, + int originPid, int originUid, uint64_t transactionId) REQUIRES(mStateLock) { uint32_t transactionFlags = 0; // start and end registration for listeners w/ no surface so they can get their callback. Note @@ -5148,7 +5310,7 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f ResolvedComposerState& composerState, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, - uint64_t transactionId) { + uint64_t transactionId) REQUIRES(mStateLock) { layer_state_t& s = composerState.state; std::vector<ListenerCallbacks> filteredListeners; @@ -5340,14 +5502,13 @@ status_t SurfaceFlinger::mirrorDisplay(DisplayId displayId, const LayerCreationA mirrorArgs.addToRoot = true; mirrorArgs.layerStackToMirror = layerStack; result = createEffectLayer(mirrorArgs, &outResult.handle, &rootMirrorLayer); + if (result != NO_ERROR) { + return result; + } outResult.layerId = rootMirrorLayer->sequence; outResult.layerName = String16(rootMirrorLayer->getDebugName()); - result |= addClientLayer(mirrorArgs, outResult.handle, rootMirrorLayer /* layer */, - nullptr /* parent */, nullptr /* outTransformHint */); - } - - if (result != NO_ERROR) { - return result; + addClientLayer(mirrorArgs, outResult.handle, rootMirrorLayer /* layer */, + nullptr /* parent */, nullptr /* outTransformHint */); } setTransactionFlags(eTransactionFlushNeeded); @@ -5367,6 +5528,9 @@ status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, gui::CreateSurface [[fallthrough]]; case ISurfaceComposerClient::eFXSurfaceEffect: { result = createBufferStateLayer(args, &outResult.handle, &layer); + if (result != NO_ERROR) { + return result; + } std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter(); if (pendingBufferCounter) { std::string counterName = layer->getPendingBufferCounterName(); @@ -5407,6 +5571,9 @@ status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, gui::CreateSurface status_t SurfaceFlinger::createBufferStateLayer(LayerCreationArgs& args, sp<IBinder>* handle, sp<Layer>* outLayer) { + if (checkLayerLeaks() != NO_ERROR) { + return NO_MEMORY; + } *outLayer = getFactory().createBufferStateLayer(args); *handle = (*outLayer)->getHandle(); return NO_ERROR; @@ -5414,11 +5581,38 @@ status_t SurfaceFlinger::createBufferStateLayer(LayerCreationArgs& args, sp<IBin status_t SurfaceFlinger::createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* handle, sp<Layer>* outLayer) { + if (checkLayerLeaks() != NO_ERROR) { + return NO_MEMORY; + } *outLayer = getFactory().createEffectLayer(args); *handle = (*outLayer)->getHandle(); return NO_ERROR; } +status_t SurfaceFlinger::checkLayerLeaks() { + if (mNumLayers >= MAX_LAYERS) { + static std::atomic<nsecs_t> lasttime{0}; + nsecs_t now = systemTime(); + if (lasttime != 0 && ns2s(now - lasttime.load()) < 10) { + ALOGE("CreateLayer already dumped 10s before"); + return NO_MEMORY; + } else { + lasttime = now; + } + + ALOGE("CreateLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(), + MAX_LAYERS); + static_cast<void>(mScheduler->schedule([&]() FTL_FAKE_GUARD(kMainThreadContext) { + ALOGE("Dumping on-screen layers."); + mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getHierarchy()); + ALOGE("Dumping off-screen layers."); + mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getOffscreenHierarchy()); + })); + return NO_MEMORY; + } + return NO_ERROR; +} + void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer, uint32_t layerId) { { // Used to remove stalled transactions which uses an internal lock. @@ -5450,7 +5644,8 @@ void SurfaceFlinger::initializeDisplays() { auto layerStack = ui::DEFAULT_LAYER_STACK.id; for (const auto& [id, display] : FTL_FAKE_GUARD(mStateLock, mPhysicalDisplays)) { - state.displays.push(DisplayState(display.token(), ui::LayerStack::fromValue(layerStack++))); + state.displays.emplace_back( + DisplayState(display.token(), ui::LayerStack::fromValue(layerStack++))); } std::vector<QueuedTransactionState> transactions; @@ -5466,7 +5661,7 @@ void SurfaceFlinger::initializeDisplays() { // In case of a restart, ensure all displays are off. for (const auto& [id, display] : mPhysicalDisplays) { - setPowerModeInternal(getDisplayDeviceLocked(id), hal::PowerMode::OFF); + setPhysicalDisplayPowerMode(getDisplayDeviceLocked(id), hal::PowerMode::OFF); } // Power on all displays. The primary display is first, so becomes the active display. Also, @@ -5475,13 +5670,14 @@ void SurfaceFlinger::initializeDisplays() { // Additionally, do not turn on displays if the boot should be quiescent. if (!mSkipPowerOnForQuiescent) { for (const auto& [id, display] : mPhysicalDisplays) { - setPowerModeInternal(getDisplayDeviceLocked(id), hal::PowerMode::ON); + setPhysicalDisplayPowerMode(getDisplayDeviceLocked(id), hal::PowerMode::ON); } } } } -void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) { +void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, + hal::PowerMode mode) { if (display->isVirtual()) { // TODO(b/241285876): This code path should not be reachable, so enforce this at compile // time. @@ -5490,7 +5686,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: } const auto displayId = display->getPhysicalId(); - ALOGD("Setting power mode %d on display %s", mode, to_string(displayId).c_str()); + ALOGD("Setting power mode %d on physical display %s", mode, to_string(displayId).c_str()); const auto currentMode = display->getPowerMode(); if (currentMode == mode) { @@ -5533,21 +5729,15 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: } if (displayId == mActiveDisplayId) { - // TODO(b/281692563): Merge the syscalls. For now, keep uclamp in a separate syscall and - // set it before SCHED_FIFO due to b/190237315. - if (setSchedAttr(true) != NO_ERROR) { - ALOGW("Failed to set uclamp.min after powering on active display: %s", - strerror(errno)); - } - if (setSchedFifo(true) != NO_ERROR) { - ALOGW("Failed to set SCHED_FIFO after powering on active display: %s", - strerror(errno)); + if (FlagManager::getInstance().correct_virtual_display_power_state()) { + applyOptimizationPolicy("setPhysicalDisplayPowerMode(ON)"); + } else { + disablePowerOptimizations("setPhysicalDisplayPowerMode(ON)"); } } getHwComposer().setPowerMode(displayId, mode); - if (mode != hal::PowerMode::DOZE_SUSPEND && - (displayId == mActiveDisplayId || FlagManager::getInstance().multithreaded_present())) { + if (mode != hal::PowerMode::DOZE_SUSPEND) { const bool enable = mScheduler->getVsyncSchedule(displayId)->getPendingHardwareVsyncState(); requestHardwareVsync(displayId, enable); @@ -5569,24 +5759,18 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: if (const auto display = getActivatableDisplay()) { onActiveDisplayChangedLocked(activeDisplay.get(), *display); } else { - if (setSchedFifo(false) != NO_ERROR) { - ALOGW("Failed to set SCHED_OTHER after powering off active display: %s", - strerror(errno)); - } - if (setSchedAttr(false) != NO_ERROR) { - ALOGW("Failed set uclamp.min after powering off active display: %s", - strerror(errno)); + if (FlagManager::getInstance().correct_virtual_display_power_state()) { + applyOptimizationPolicy("setPhysicalDisplayPowerMode(OFF)"); + } else { + enablePowerOptimizations("setPhysicalDisplayPowerMode(OFF)"); } if (currentModeNotDozeSuspend) { - if (!FlagManager::getInstance().multithreaded_present()) { - mScheduler->disableHardwareVsync(displayId, true); - } mScheduler->enableSyntheticVsync(); } } } - if (currentModeNotDozeSuspend && FlagManager::getInstance().multithreaded_present()) { + if (currentModeNotDozeSuspend) { constexpr bool kDisallow = true; mScheduler->disableHardwareVsync(displayId, kDisallow); } @@ -5604,8 +5788,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: } else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) { // Update display while dozing getHwComposer().setPowerMode(displayId, mode); - if (currentMode == hal::PowerMode::DOZE_SUSPEND && - (displayId == mActiveDisplayId || FlagManager::getInstance().multithreaded_present())) { + if (currentMode == hal::PowerMode::DOZE_SUSPEND) { if (displayId == mActiveDisplayId) { ALOGI("Force repainting for DOZE_SUSPEND -> DOZE or ON."); mVisibleRegionsDirty = true; @@ -5617,10 +5800,9 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: } } else if (mode == hal::PowerMode::DOZE_SUSPEND) { // Leave display going to doze - if (displayId == mActiveDisplayId || FlagManager::getInstance().multithreaded_present()) { - constexpr bool kDisallow = true; - mScheduler->disableHardwareVsync(displayId, kDisallow); - } + constexpr bool kDisallow = true; + mScheduler->disableHardwareVsync(displayId, kDisallow); + if (displayId == mActiveDisplayId) { mScheduler->enableSyntheticVsync(); } @@ -5637,21 +5819,96 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: mScheduler->setDisplayPowerMode(displayId, mode); - ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str()); + ALOGD("Finished setting power mode %d on physical display %s", mode, + to_string(displayId).c_str()); +} + +void SurfaceFlinger::setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, + hal::PowerMode mode) { + if (!display->isVirtual()) { + ALOGE("%s: Invalid operation on physical display", __func__); + return; + } + + const auto displayId = display->getVirtualId(); + ALOGD("Setting power mode %d on virtual display %s %s", mode, to_string(displayId).c_str(), + display->getDisplayName().c_str()); + + display->setPowerMode(static_cast<hal::PowerMode>(mode)); + + applyOptimizationPolicy(__func__); + + ALOGD("Finished setting power mode %d on virtual display %s", mode, + to_string(displayId).c_str()); +} + +bool SurfaceFlinger::shouldOptimizeForPerformance() { + for (const auto& [_, display] : mDisplays) { + // Displays that are optimized for power are always powered on and should not influence + // whether there is an active display for the purpose of power optimization, etc. If these + // displays are being shown somewhere, a different (physical or virtual) display that is + // optimized for performance will be powered on in addition. Displays optimized for + // performance will change power mode, so if they are off then they are not active. + if (display->isPoweredOn() && + display->getOptimizationPolicy() == + gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) { + return true; + } + } + return false; +} + +void SurfaceFlinger::enablePowerOptimizations(const char* whence) { + ALOGD("%s: Enabling power optimizations", whence); + + setSchedAttr(false, whence); + setSchedFifo(false, whence); +} + +void SurfaceFlinger::disablePowerOptimizations(const char* whence) { + ALOGD("%s: Disabling power optimizations", whence); + + // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall + // and set it before SCHED_FIFO due to b/190237315. + setSchedAttr(true, whence); + setSchedFifo(true, whence); +} + +void SurfaceFlinger::applyOptimizationPolicy(const char* whence) { + if (shouldOptimizeForPerformance()) { + disablePowerOptimizations(whence); + } else { + enablePowerOptimizations(whence); + } } void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { - auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD( - kMainThreadContext) { + auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) { mSkipPowerOnForQuiescent = false; - const auto display = getDisplayDeviceLocked(displayToken); + const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayToken)); if (!display) { - ALOGE("Attempt to set power mode %d for invalid display token %p", mode, - displayToken.get()); + Mutex::Autolock lock(mStateLock); + const ssize_t index = mCurrentState.displays.indexOfKey(displayToken); + if (index >= 0) { + auto& state = mCurrentState.displays.editValueFor(displayToken); + if (state.isVirtual()) { + ALOGD("Setting power mode %d for a dormant virtual display with token %p", mode, + displayToken.get()); + state.initialPowerMode = static_cast<hal::PowerMode>(mode); + return; + } + } + ALOGE("Failed to set power mode %d for display token %p", mode, displayToken.get()); } else if (display->isVirtual()) { - ALOGW("Attempt to set power mode %d for virtual display", mode); + if (FlagManager::getInstance().correct_virtual_display_power_state()) { + ftl::FakeGuard guard(mStateLock); + setVirtualDisplayPowerMode(display, static_cast<hal::PowerMode>(mode)); + } else { + ALOGW("Attempt to set power mode %d for virtual display", mode); + } } else { - setPowerModeInternal(display, static_cast<hal::PowerMode>(mode)); + ftl::FakeGuard guard(mStateLock); + setPhysicalDisplayPowerMode(display, static_cast<hal::PowerMode>(mode)); } }); @@ -5845,17 +6102,15 @@ void SurfaceFlinger::dumpDisplays(std::string& result) const { for (const auto& [token, display] : mDisplays) { if (display->isVirtual()) { - const auto displayId = display->getId(); + const VirtualDisplayId virtualId = display->getVirtualId(); utils::Dumper::Section section(dumper, - ftl::Concat("Virtual Display ", displayId.value).str()); + ftl::Concat("Virtual Display ", virtualId.value).str()); display->dump(dumper); - if (const auto virtualIdOpt = VirtualDisplayId::tryCast(displayId)) { - std::lock_guard lock(mVirtualDisplaysMutex); - const auto virtualSnapshotIt = mVirtualDisplays.find(virtualIdOpt.value()); - if (virtualSnapshotIt != mVirtualDisplays.end()) { - virtualSnapshotIt->second.dump(dumper); - } + std::lock_guard lock(mVirtualDisplaysMutex); + const auto virtualSnapshotIt = mVirtualDisplays.find(virtualId); + if (virtualSnapshotIt != mVirtualDisplays.end()) { + virtualSnapshotIt->second.dump(dumper); } } } @@ -5863,7 +6118,7 @@ void SurfaceFlinger::dumpDisplays(std::string& result) const { void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const { for (const auto& [token, display] : mDisplays) { - const auto displayId = PhysicalDisplayId::tryCast(display->getId()); + const auto displayId = asPhysicalDisplayId(display->getDisplayIdVariant()); if (!displayId) { continue; } @@ -6072,7 +6327,7 @@ perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t t void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const { for (const auto& [token, display] : mDisplays) { - const auto displayId = HalDisplayId::tryCast(display->getId()); + const auto displayId = asHalDisplayId(display->getDisplayIdVariant()); if (!displayId) { continue; } @@ -6655,8 +6910,9 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r return getDefaultDisplayDevice()->getDisplayToken().promote(); } - if (const auto id = DisplayId::fromValue<PhysicalDisplayId>(value)) { - return getPhysicalDisplayToken(*id); + if (const auto token = + getPhysicalDisplayToken(PhysicalDisplayId::fromValue(value))) { + return token; } ALOGE("Invalid physical display ID"); @@ -6754,10 +7010,10 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r case 1040: { auto future = mScheduler->schedule([&] { n = data.readInt32(); - std::optional<PhysicalDisplayId> inputId = std::nullopt; + PhysicalDisplayId inputId; if (uint64_t inputDisplayId; data.readUint64(&inputDisplayId) == NO_ERROR) { - inputId = DisplayId::fromValue<PhysicalDisplayId>(inputDisplayId); - if (!inputId || getPhysicalDisplayToken(*inputId)) { + inputId = PhysicalDisplayId::fromValue(inputDisplayId); + if (!getPhysicalDisplayToken(inputId)) { ALOGE("No display with id: %" PRIu64, inputDisplayId); return NAME_NOT_FOUND; } @@ -6766,7 +7022,7 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r Mutex::Autolock lock(mStateLock); mLayerCachingEnabled = n != 0; for (const auto& [_, display] : mDisplays) { - if (!inputId || *inputId == display->getPhysicalId()) { + if (inputId == display->getPhysicalId()) { display->enableLayerCaching(mLayerCachingEnabled); } } @@ -6849,11 +7105,10 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r int64_t arg1 = data.readInt64(); int64_t arg2 = data.readInt64(); // Enable mirroring for one display - const auto display1id = DisplayId::fromValue(arg1); auto mirrorRoot = SurfaceComposerClient::getDefault()->mirrorDisplay( - display1id.value()); - auto id2 = DisplayId::fromValue<PhysicalDisplayId>(arg2); - const auto token2 = getPhysicalDisplayToken(*id2); + DisplayId::fromValue(arg1)); + const auto token2 = + getPhysicalDisplayToken(PhysicalDisplayId::fromValue(arg2)); ui::LayerStack layerStack; { Mutex::Autolock lock(mStateLock); @@ -7039,13 +7294,13 @@ static status_t validateScreenshotPermissions(const CaptureArgs& captureArgs) { return PERMISSION_DENIED; } -status_t SurfaceFlinger::setSchedFifo(bool enabled) { +void SurfaceFlinger::setSchedFifo(bool enabled, const char* whence) { static constexpr int kFifoPriority = 2; static constexpr int kOtherPriority = 0; struct sched_param param = {0}; int sched_policy; - if (enabled) { + if (enabled && !FlagManager::getInstance().disable_sched_fifo_sf()) { sched_policy = SCHED_FIFO; param.sched_priority = kFifoPriority; } else { @@ -7054,19 +7309,19 @@ status_t SurfaceFlinger::setSchedFifo(bool enabled) { } if (sched_setscheduler(0, sched_policy, ¶m) != 0) { - return -errno; + const char* kPolicy[] = {"SCHED_OTHER", "SCHED_FIFO"}; + ALOGW("%s: Failed to set %s: %s", whence, kPolicy[sched_policy == SCHED_FIFO], + strerror(errno)); } - - return NO_ERROR; } -status_t SurfaceFlinger::setSchedAttr(bool enabled) { +void SurfaceFlinger::setSchedAttr(bool enabled, const char* whence) { static const unsigned int kUclampMin = base::GetUintProperty<unsigned int>("ro.surface_flinger.uclamp.min"s, 0U); if (!kUclampMin) { // uclamp.min set to 0 (default), skip setting - return NO_ERROR; + return; } sched_attr attr = {}; @@ -7077,22 +7332,20 @@ status_t SurfaceFlinger::setSchedAttr(bool enabled) { attr.sched_util_max = 1024; if (syscall(__NR_sched_setattr, 0, &attr, 0)) { - return -errno; + const char* kAction[] = {"disable", "enable"}; + ALOGW("%s: Failed to %s uclamp.min: %s", whence, kAction[enabled], strerror(errno)); } - - return NO_ERROR; } namespace { -ui::Dataspace pickBestDataspace(ui::Dataspace requestedDataspace, - const compositionengine::impl::OutputCompositionState& state, +ui::Dataspace pickBestDataspace(ui::Dataspace requestedDataspace, ui::ColorMode colorMode, bool capturingHdrLayers, bool hintForSeamlessTransition) { if (requestedDataspace != ui::Dataspace::UNKNOWN) { return requestedDataspace; } - const auto dataspaceForColorMode = ui::pickDataspaceFor(state.colorMode); + const auto dataspaceForColorMode = ui::pickDataspaceFor(colorMode); // TODO: Enable once HDR screenshots are ready. if constexpr (/* DISABLES CODE */ (false)) { @@ -7141,9 +7394,13 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, } wp<const DisplayDevice> displayWeak; + ftl::Optional<DisplayIdVariant> displayIdVariantOpt; ui::LayerStack layerStack; ui::Size reqSize(args.width, args.height); std::unordered_set<uint32_t> excludeLayerIds; + Rect layerStackSpaceRect; + bool displayIsSecure; + { Mutex::Autolock lock(mStateLock); sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken); @@ -7153,11 +7410,14 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, return; } displayWeak = display; + displayIdVariantOpt = display->getDisplayIdVariant(); layerStack = display->getLayerStack(); + displayIsSecure = display->isSecure(); + layerStackSpaceRect = display->getLayerStackSpaceRect(); // set the requested width/height to the logical display layer stack rect size by default if (args.width == 0 || args.height == 0) { - reqSize = display->getLayerStackSpaceRect().getSize(); + reqSize = layerStackSpaceRect.getSize(); } for (const auto& handle : captureArgs.excludeHandles) { @@ -7176,16 +7436,19 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, getLayerSnapshotsForScreenshots(layerStack, captureArgs.uid, std::move(excludeLayerIds)); - ftl::Flags<RenderArea::Options> options; - if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS; - if (captureArgs.hintForSeamlessTransition) - options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION; - captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>, - gui::aidl_utils::fromARect(captureArgs.sourceCrop), - reqSize, - static_cast<ui::Dataspace>(captureArgs.dataspace), - displayWeak, options), - getLayerSnapshotsFn, reqSize, + ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = displayWeak; + screenshotArgs.displayIdVariant = displayIdVariantOpt; + screenshotArgs.sourceCrop = gui::aidl_utils::fromARect(captureArgs.sourceCrop); + if (screenshotArgs.sourceCrop.isEmpty()) { + screenshotArgs.sourceCrop = layerStackSpaceRect; + } + screenshotArgs.reqSize = reqSize; + screenshotArgs.dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace); + screenshotArgs.isSecure = captureArgs.captureSecureLayers && displayIsSecure; + screenshotArgs.seamlessTransition = captureArgs.hintForSeamlessTransition; + + captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, reqSize, static_cast<ui::PixelFormat>(captureArgs.pixelFormat), captureArgs.allowProtected, captureArgs.grayscale, captureListener); } @@ -7194,7 +7457,11 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args const sp<IScreenCaptureListener>& captureListener) { ui::LayerStack layerStack; wp<const DisplayDevice> displayWeak; + ftl::Optional<DisplayIdVariant> displayIdVariantOpt; ui::Size size; + Rect layerStackSpaceRect; + bool displayIsSecure; + { Mutex::Autolock lock(mStateLock); @@ -7206,8 +7473,11 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args } displayWeak = display; + displayIdVariantOpt = display->getDisplayIdVariant(); layerStack = display->getLayerStack(); + layerStackSpaceRect = display->getLayerStackSpaceRect(); size = display->getLayerStackSpaceRect().getSize(); + displayIsSecure = display->isSecure(); } size.width *= args.frameScaleX; @@ -7236,15 +7506,18 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args constexpr bool kAllowProtected = false; constexpr bool kGrayscale = false; - ftl::Flags<RenderArea::Options> options; - if (args.hintForSeamlessTransition) - options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION; - captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>, - Rect(), size, - static_cast<ui::Dataspace>(args.dataspace), - displayWeak, options), - getLayerSnapshotsFn, size, static_cast<ui::PixelFormat>(args.pixelFormat), - kAllowProtected, kGrayscale, captureListener); + ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = displayWeak; + screenshotArgs.displayIdVariant = displayIdVariantOpt; + screenshotArgs.sourceCrop = layerStackSpaceRect; + screenshotArgs.reqSize = size; + screenshotArgs.dataspace = static_cast<ui::Dataspace>(args.dataspace); + screenshotArgs.isSecure = args.captureSecureLayers && displayIsSecure; + screenshotArgs.seamlessTransition = args.hintForSeamlessTransition; + + captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, size, + static_cast<ui::PixelFormat>(args.pixelFormat), kAllowProtected, kGrayscale, + captureListener); } ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& args) { @@ -7346,14 +7619,16 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, return; } - ftl::Flags<RenderArea::Options> options; - if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS; - if (captureArgs.hintForSeamlessTransition) - options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION; - captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<LayerRenderAreaBuilder>, crop, - reqSize, dataspace, parent, args.childrenOnly, - options), - getLayerSnapshotsFn, reqSize, + ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = parent->getSequence(); + screenshotArgs.childrenOnly = args.childrenOnly; + screenshotArgs.sourceCrop = crop; + screenshotArgs.reqSize = reqSize; + screenshotArgs.dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace); + screenshotArgs.isSecure = captureArgs.captureSecureLayers; + screenshotArgs.seamlessTransition = captureArgs.hintForSeamlessTransition; + + captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, reqSize, static_cast<ui::PixelFormat>(captureArgs.pixelFormat), captureArgs.allowProtected, captureArgs.grayscale, captureListener); } @@ -7384,15 +7659,17 @@ bool SurfaceFlinger::layersHasProtectedLayer( return protectedLayerFound; } -// Getting layer snapshots and display should take place on main thread. -// Accessing display requires mStateLock, and contention for this lock -// is reduced when grabbed from the main thread, thus also reducing -// risk of deadlocks. -std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getSnapshotsFromMainThread( - RenderAreaBuilderVariant& renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn, +// Getting layer snapshots and accessing display state should take place on +// main thread. Accessing display requires mStateLock, and contention for +// this lock is reduced when grabbed from the main thread, thus also reducing +// risk of deadlocks. Returns false if no display is found. +bool SurfaceFlinger::getSnapshotsFromMainThread( + ScreenshotArgs& args, GetLayerSnapshotsFunction getLayerSnapshotsFn, std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) { return mScheduler - ->schedule([=, this, &renderAreaBuilder, &layers]() REQUIRES(kMainThreadContext) { + ->schedule([=, this, &args, &layers]() REQUIRES(kMainThreadContext) { + SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Screenshot"); + mPowerAdvisor->setScreenshotWorkload(); SFTRACE_NAME("getSnapshotsFromMainThread"); layers = getLayerSnapshotsFn(); // Non-threaded RenderEngine eventually returns to the main thread a 2nd time @@ -7405,12 +7682,12 @@ std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getSnapsho ui::INVALID_LAYER_STACK); } } - return getDisplayStateFromRenderAreaBuilder(renderAreaBuilder); + return getDisplayStateOnMainThread(args); }) .get(); } -void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuilder, +void SurfaceFlinger::captureScreenCommon(ScreenshotArgs& args, GetLayerSnapshotsFunction getLayerSnapshotsFn, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool grayscale, @@ -7426,7 +7703,11 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil } std::vector<std::pair<Layer*, sp<LayerFE>>> layers; - auto displayState = getSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, layers); + bool hasDisplayState = getSnapshotsFromMainThread(args, getLayerSnapshotsFn, layers); + if (!hasDisplayState) { + ALOGD("Display state not found"); + invokeScreenCaptureError(NO_MEMORY, captureListener); + } const bool hasHdrLayer = std::any_of(layers.cbegin(), layers.cend(), [this](const auto& layer) { return isHdrLayer(*(layer.second->mSnapshot.get())); @@ -7464,12 +7745,8 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil std::shared_ptr<renderengine::impl::ExternalTexture> hdrTexture; std::shared_ptr<renderengine::impl::ExternalTexture> gainmapTexture; - bool hintForSeamless = std::visit( - [](auto&& arg) { - return arg.options.test(RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION); - }, - renderAreaBuilder); - if (hasHdrLayer && !hintForSeamless && FlagManager::getInstance().true_hdr_screenshots()) { + if (hasHdrLayer && !args.seamlessTransition && + FlagManager::getInstance().true_hdr_screenshots()) { const auto hdrBuffer = getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(), HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */, @@ -7502,35 +7779,42 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil } } - auto futureFence = captureScreenshot(renderAreaBuilder, texture, false /* regionSampling */, - grayscale, isProtected, captureListener, displayState, - layers, hdrTexture, gainmapTexture); + auto futureFence = + captureScreenshot(args, texture, false /* regionSampling */, grayscale, isProtected, + captureListener, layers, hdrTexture, gainmapTexture); futureFence.get(); } -std::optional<SurfaceFlinger::OutputCompositionState> -SurfaceFlinger::getDisplayStateFromRenderAreaBuilder(RenderAreaBuilderVariant& renderAreaBuilder) { +// Returns true if display is found and args was populated with display state +// data. Otherwise, returns false. +bool SurfaceFlinger::getDisplayStateOnMainThread(ScreenshotArgs& args) { sp<const DisplayDevice> display = nullptr; { Mutex::Autolock lock(mStateLock); - if (auto* layerRenderAreaBuilder = - std::get_if<LayerRenderAreaBuilder>(&renderAreaBuilder)) { + // Screenshot initiated through captureLayers + if (auto* layerSequence = std::get_if<int32_t>(&args.captureTypeVariant)) { // LayerSnapshotBuilder should only be accessed from the main thread. const frontend::LayerSnapshot* snapshot = - mLayerSnapshotBuilder.getSnapshot(layerRenderAreaBuilder->layer->getSequence()); + mLayerSnapshotBuilder.getSnapshot(*layerSequence); if (!snapshot) { - ALOGW("Couldn't find layer snapshot for %d", - layerRenderAreaBuilder->layer->getSequence()); + ALOGW("Couldn't find layer snapshot for %d", *layerSequence); } else { - layerRenderAreaBuilder->setLayerSnapshot(*snapshot); + if (!args.childrenOnly) { + args.transform = snapshot->localTransform.inverse(); + } + if (args.sourceCrop.isEmpty()) { + args.sourceCrop = snapshot->bufferSize; + } display = findDisplay( [layerStack = snapshot->outputFilter.layerStack](const auto& display) { return display.getLayerStack() == layerStack; }); } - } else if (auto* displayRenderAreaBuilder = - std::get_if<DisplayRenderAreaBuilder>(&renderAreaBuilder)) { - display = displayRenderAreaBuilder->displayWeak.promote(); + + // Screenshot initiated through captureDisplay + } else if (auto* displayWeak = + std::get_if<wp<const DisplayDevice>>(&args.captureTypeVariant)) { + display = displayWeak->promote(); } if (display == nullptr) { @@ -7538,79 +7822,66 @@ SurfaceFlinger::getDisplayStateFromRenderAreaBuilder(RenderAreaBuilderVariant& r } if (display != nullptr) { - return std::optional{display->getCompositionDisplay()->getState()}; + const auto& state = display->getCompositionDisplay()->getState(); + args.displayBrightnessNits = state.displayBrightnessNits; + args.sdrWhitePointNits = state.sdrWhitePointNits; + args.renderIntent = state.renderIntent; + args.colorMode = state.colorMode; + return true; } } - return std::nullopt; + return false; } ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( - const RenderAreaBuilderVariant& renderAreaBuilder, - const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener, - const std::optional<OutputCompositionState>& displayState, + ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer, + bool regionSampling, bool grayscale, bool isProtected, + const sp<IScreenCaptureListener>& captureListener, const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers, const std::shared_ptr<renderengine::ExternalTexture>& hdrBuffer, const std::shared_ptr<renderengine::ExternalTexture>& gainmapBuffer) { SFTRACE_CALL(); ScreenCaptureResults captureResults; - std::unique_ptr<const RenderArea> renderArea = - std::visit([](auto&& arg) -> std::unique_ptr<RenderArea> { return arg.build(); }, - renderAreaBuilder); - - if (!renderArea) { - ALOGW("Skipping screen capture because of invalid render area."); - if (captureListener) { - captureResults.fenceResult = base::unexpected(NO_MEMORY); - captureListener->onScreenCaptureCompleted(captureResults); - } - return ftl::yield<FenceResult>(base::unexpected(NO_ERROR)).share(); - } - - float displayBrightnessNits = displayState.value().displayBrightnessNits; - float sdrWhitePointNits = displayState.value().sdrWhitePointNits; - ftl::SharedFuture<FenceResult> renderFuture; + float hdrSdrRatio = args.displayBrightnessNits / args.sdrWhitePointNits; + if (hdrBuffer && gainmapBuffer) { ftl::SharedFuture<FenceResult> hdrRenderFuture = - renderScreenImpl(renderArea.get(), hdrBuffer, regionSampling, grayscale, - isProtected, captureResults, displayState, layers); + renderScreenImpl(args, hdrBuffer, regionSampling, grayscale, isProtected, + captureResults, layers); captureResults.buffer = buffer->getBuffer(); captureResults.optionalGainMap = gainmapBuffer->getBuffer(); renderFuture = ftl::Future(std::move(hdrRenderFuture)) - .then([&, displayBrightnessNits, sdrWhitePointNits, - dataspace = captureResults.capturedDataspace, buffer, hdrBuffer, - gainmapBuffer](FenceResult fenceResult) -> FenceResult { + .then([&, hdrSdrRatio, dataspace = captureResults.capturedDataspace, buffer, + hdrBuffer, gainmapBuffer](FenceResult fenceResult) -> FenceResult { if (!fenceResult.ok()) { return fenceResult; } return getRenderEngine() .tonemapAndDrawGainmap(hdrBuffer, fenceResult.value()->get(), - displayBrightnessNits / - sdrWhitePointNits, + hdrSdrRatio, static_cast<ui::Dataspace>(dataspace), buffer, gainmapBuffer) .get(); }) .share(); } else { - renderFuture = renderScreenImpl(renderArea.get(), buffer, regionSampling, grayscale, - isProtected, captureResults, displayState, layers); + renderFuture = renderScreenImpl(args, buffer, regionSampling, grayscale, isProtected, + captureResults, layers); } if (captureListener) { // Defer blocking on renderFuture back to the Binder thread. return ftl::Future(std::move(renderFuture)) .then([captureListener, captureResults = std::move(captureResults), - displayBrightnessNits, - sdrWhitePointNits](FenceResult fenceResult) mutable -> FenceResult { + hdrSdrRatio](FenceResult fenceResult) mutable -> FenceResult { captureResults.fenceResult = std::move(fenceResult); - captureResults.hdrSdrRatio = displayBrightnessNits / sdrWhitePointNits; + captureResults.hdrSdrRatio = hdrSdrRatio; captureListener->onScreenCaptureCompleted(captureResults); return base::unexpected(NO_ERROR); }) @@ -7620,9 +7891,8 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( } ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( - const RenderArea* renderArea, const std::shared_ptr<renderengine::ExternalTexture>& buffer, + ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults& captureResults, - const std::optional<OutputCompositionState>& displayState, const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) { SFTRACE_CALL(); @@ -7631,57 +7901,43 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( captureResults.capturedSecureLayers |= (snapshot->isVisible && snapshot->isSecure); captureResults.capturedHdrLayers |= isHdrLayer(*snapshot); layerFE->mSnapshot->geomLayerTransform = - renderArea->getTransform() * layerFE->mSnapshot->geomLayerTransform; + args.transform * layerFE->mSnapshot->geomLayerTransform; layerFE->mSnapshot->geomInverseLayerTransform = layerFE->mSnapshot->geomLayerTransform.inverse(); } - auto capturedBuffer = buffer; - - auto requestedDataspace = renderArea->getReqDataSpace(); - auto parent = renderArea->getParentLayer(); - auto renderIntent = RenderIntent::TONE_MAP_COLORIMETRIC; - auto sdrWhitePointNits = DisplayDevice::sDefaultMaxLumiance; - auto displayBrightnessNits = DisplayDevice::sDefaultMaxLumiance; - - captureResults.capturedDataspace = requestedDataspace; + const bool enableLocalTonemapping = + FlagManager::getInstance().local_tonemap_screenshots() && !args.seamlessTransition; - const bool enableLocalTonemapping = FlagManager::getInstance().local_tonemap_screenshots() && - !renderArea->getHintForSeamlessTransition(); + captureResults.capturedDataspace = + pickBestDataspace(args.dataspace, args.colorMode, captureResults.capturedHdrLayers, + args.seamlessTransition); - if (displayState) { - const auto& state = displayState.value(); - captureResults.capturedDataspace = - pickBestDataspace(requestedDataspace, state, captureResults.capturedHdrLayers, - renderArea->getHintForSeamlessTransition()); - sdrWhitePointNits = state.sdrWhitePointNits; - - if (!captureResults.capturedHdrLayers) { - displayBrightnessNits = sdrWhitePointNits; - } else { - displayBrightnessNits = state.displayBrightnessNits; - if (!enableLocalTonemapping) { - // Only clamp the display brightness if this is not a seamless transition. - // Otherwise for seamless transitions it's important to match the current - // display state as the buffer will be shown under these same conditions, and we - // want to avoid any flickers - if (sdrWhitePointNits > 1.0f && !renderArea->getHintForSeamlessTransition()) { - // Restrict the amount of HDR "headroom" in the screenshot to avoid - // over-dimming the SDR portion. 2.0 chosen by experimentation - constexpr float kMaxScreenshotHeadroom = 2.0f; - displayBrightnessNits = std::min(sdrWhitePointNits * kMaxScreenshotHeadroom, - displayBrightnessNits); - } - } + // Only clamp the display brightness if this is not a seamless transition. + // Otherwise for seamless transitions it's important to match the current + // display state as the buffer will be shown under these same conditions, and we + // want to avoid any flickers. + if (captureResults.capturedHdrLayers) { + if (!enableLocalTonemapping && args.sdrWhitePointNits > 1.0f && !args.seamlessTransition) { + // Restrict the amount of HDR "headroom" in the screenshot to avoid + // over-dimming the SDR portion. 2.0 chosen by experimentation + constexpr float kMaxScreenshotHeadroom = 2.0f; + // TODO: Aim to update displayBrightnessNits earlier in screenshot + // path so ScreenshotArgs can be passed as const + args.displayBrightnessNits = std::min(args.sdrWhitePointNits * kMaxScreenshotHeadroom, + args.displayBrightnessNits); } + } else { + args.displayBrightnessNits = args.sdrWhitePointNits; + } - // Screenshots leaving the device should be colorimetric - if (requestedDataspace == ui::Dataspace::UNKNOWN && - renderArea->getHintForSeamlessTransition()) { - renderIntent = state.renderIntent; - } + auto renderIntent = RenderIntent::TONE_MAP_COLORIMETRIC; + // Screenshots leaving the device should be colorimetric + if (args.dataspace == ui::Dataspace::UNKNOWN && args.seamlessTransition) { + renderIntent = args.renderIntent; } + auto capturedBuffer = buffer; captureResults.buffer = capturedBuffer->getBuffer(); ui::LayerStack layerStack{ui::DEFAULT_LAYER_STACK}; @@ -7691,12 +7947,12 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( } auto present = [this, buffer = capturedBuffer, dataspace = captureResults.capturedDataspace, - sdrWhitePointNits, displayBrightnessNits, grayscale, isProtected, layers, - layerStack, regionSampling, renderArea = std::move(renderArea), renderIntent, + grayscale, isProtected, layers, layerStack, regionSampling, args, renderIntent, enableLocalTonemapping]() -> FenceResult { std::unique_ptr<compositionengine::CompositionEngine> compositionEngine = mFactory.createCompositionEngine(); compositionEngine->setRenderEngine(mRenderEngine.get()); + compositionEngine->setHwComposer(mHWComposer.get()); std::vector<sp<compositionengine::LayerFE>> layerFEs; layerFEs.reserve(layers.size()); @@ -7717,9 +7973,10 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( if (enableLocalTonemapping) { // Boost the whole scene so that SDR white is at 1.0 while still communicating the hdr // sdr ratio via display brightness / sdrWhite nits. - targetBrightness = sdrWhitePointNits / displayBrightnessNits; + targetBrightness = args.sdrWhitePointNits / args.displayBrightnessNits; } else if (dataspace == ui::Dataspace::BT2020_HLG) { - const float maxBrightnessNits = displayBrightnessNits / sdrWhitePointNits * 203; + const float maxBrightnessNits = + args.displayBrightnessNits / args.sdrWhitePointNits * 203; // With a low dimming ratio, don't fit the entire curve. Otherwise mixed content // will appear way too bright. if (maxBrightnessNits < 1000.f) { @@ -7727,23 +7984,33 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( } } + // Capturing screenshots using layers have a clear capture fill (0 alpha). + // Capturing via display or displayId, which do not use args.layerSequence, + // has an opaque capture fill (1 alpha). + const float layerAlpha = + std::holds_alternative<int32_t>(args.captureTypeVariant) ? 0.0f : 1.0f; + // Screenshots leaving the device must not dim in gamma space. - const bool dimInGammaSpaceForEnhancedScreenshots = mDimInGammaSpaceForEnhancedScreenshots && - renderArea->getHintForSeamlessTransition(); + const bool dimInGammaSpaceForEnhancedScreenshots = + mDimInGammaSpaceForEnhancedScreenshots && args.seamlessTransition; std::shared_ptr<ScreenCaptureOutput> output = createScreenCaptureOutput( ScreenCaptureOutputArgs{.compositionEngine = *compositionEngine, .colorProfile = colorProfile, - .renderArea = *renderArea, .layerStack = layerStack, + .sourceCrop = args.sourceCrop, .buffer = std::move(buffer), - .sdrWhitePointNits = sdrWhitePointNits, - .displayBrightnessNits = displayBrightnessNits, + .displayIdVariant = args.displayIdVariant, + .reqBufferSize = args.reqSize, + .sdrWhitePointNits = args.sdrWhitePointNits, + .displayBrightnessNits = args.displayBrightnessNits, .targetBrightness = targetBrightness, + .layerAlpha = layerAlpha, .regionSampling = regionSampling, .treat170mAsSrgb = mTreat170mAsSrgb, .dimInGammaSpaceForEnhancedScreenshots = dimInGammaSpaceForEnhancedScreenshots, + .isSecure = args.isSecure, .isProtected = isProtected, .enableLocalTonemapping = enableLocalTonemapping}); @@ -7832,9 +8099,8 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy( const scheduler::RefreshRateSelector::Policy currentPolicy = selector.getCurrentPolicy(); ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str()); - if (const bool isPacesetter = - mScheduler->onDisplayModeChanged(displayId, selector.getActiveMode(), - /*clearContentRequirements*/ true)) { + if (mScheduler->onDisplayModeChanged(displayId, selector.getActiveMode(), + /*clearContentRequirements*/ true)) { mDisplayModeController.updateKernelIdleTimer(displayId); } @@ -8068,11 +8334,13 @@ int SurfaceFlinger::getGpuContextPriority() { int SurfaceFlinger::calculateMaxAcquiredBufferCount(Fps refreshRate, std::chrono::nanoseconds presentLatency) { - auto pipelineDepth = presentLatency.count() / refreshRate.getPeriodNsecs(); + int64_t pipelineDepth = presentLatency.count() / refreshRate.getPeriodNsecs(); if (presentLatency.count() % refreshRate.getPeriodNsecs()) { pipelineDepth++; } - return std::max(minAcquiredBuffers, static_cast<int64_t>(pipelineDepth - 1)); + const int64_t maxAcquiredBuffers = + std::min(pipelineDepth - 1, maxAcquiredBuffersOpt.value_or(pipelineDepth - 1)); + return std::max(minAcquiredBuffers, maxAcquiredBuffers); } status_t SurfaceFlinger::getMaxAcquiredBufferCount(int* buffers) const { @@ -8132,8 +8400,8 @@ sp<DisplayDevice> SurfaceFlinger::getActivatableDisplay() const { // TODO(b/255635821): Choose the pacesetter display, considering both internal and external // displays. For now, pick the other internal display, assuming a dual-display foldable. return findDisplay([this](const DisplayDevice& display) REQUIRES(mStateLock) { - const auto idOpt = PhysicalDisplayId::tryCast(display.getId()); - return idOpt && *idOpt != mActiveDisplayId && display.isPoweredOn() && + const auto idOpt = asPhysicalDisplayId(display.getDisplayIdVariant()); + return idOpt.has_value() && *idOpt != mActiveDisplayId && display.isPoweredOn() && mPhysicalDisplays.get(*idOpt) .transform(&PhysicalDisplay::isInternal) .value_or(false); @@ -8190,10 +8458,6 @@ status_t SurfaceFlinger::getStalledTransactionInfo( void SurfaceFlinger::updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t connectedLevel, int32_t maxLevel) { - if (!FlagManager::getInstance().connected_display()) { - return; - } - Mutex::Autolock lock(mStateLock); const auto idOpt = getHwComposer().toPhysicalDisplayId(hwcDisplayId); @@ -8577,16 +8841,16 @@ binder::Status SurfaceComposerAIDL::createConnection(sp<gui::ISurfaceComposerCli } } -binder::Status SurfaceComposerAIDL::createVirtualDisplay(const std::string& displayName, - bool isSecure, const std::string& uniqueId, - float requestedRefreshRate, - sp<IBinder>* outDisplay) { +binder::Status SurfaceComposerAIDL::createVirtualDisplay( + const std::string& displayName, bool isSecure, + gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy, const std::string& uniqueId, + float requestedRefreshRate, sp<IBinder>* outDisplay) { status_t status = checkAccessPermission(); if (status != OK) { return binderStatusFromStatusT(status); } - *outDisplay = - mFlinger->createVirtualDisplay(displayName, isSecure, uniqueId, requestedRefreshRate); + *outDisplay = mFlinger->createVirtualDisplay(displayName, isSecure, optimizationPolicy, + uniqueId, requestedRefreshRate); return binder::Status::ok(); } @@ -8615,8 +8879,8 @@ binder::Status SurfaceComposerAIDL::getPhysicalDisplayToken(int64_t displayId, if (status != OK) { return binderStatusFromStatusT(status); } - const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId)); - *outDisplay = mFlinger->getPhysicalDisplayToken(*id); + const PhysicalDisplayId id = PhysicalDisplayId::fromValue(static_cast<uint64_t>(displayId)); + *outDisplay = mFlinger->getPhysicalDisplayToken(id); return binder::Status::ok(); } @@ -8674,6 +8938,7 @@ binder::Status SurfaceComposerAIDL::getStaticDisplayInfo(int64_t displayId, if (status == NO_ERROR) { // convert ui::StaticDisplayInfo to gui::StaticDisplayInfo outInfo->connectionType = static_cast<gui::DisplayConnectionType>(info.connectionType); + outInfo->port = info.port; outInfo->density = info.density; outInfo->secure = info.secure; outInfo->installOrientation = static_cast<gui::Rotation>(info.installOrientation); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c2e687f385..9cf0c6aaa0 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -70,12 +70,12 @@ #include <common/FlagManager.h> #include "ActivePictureTracker.h" -#include "BackgroundExecutor.h" #include "Display/DisplayModeController.h" #include "Display/PhysicalDisplay.h" #include "Display/VirtualDisplaySnapshot.h" #include "DisplayDevice.h" #include "DisplayHardware/HWC2.h" +#include "DisplayHardware/HWComposer.h" #include "DisplayIdGenerator.h" #include "Effects/Daltonizer.h" #include "FrontEnd/DisplayInfo.h" @@ -102,12 +102,9 @@ #include <atomic> #include <cstdint> #include <functional> -#include <map> #include <memory> #include <mutex> #include <optional> -#include <queue> -#include <set> #include <string> #include <thread> #include <type_traits> @@ -130,13 +127,11 @@ class FlagManager; class FpsReporter; class TunnelModeEnabledReporter; class HdrLayerInfoReporter; -class HWComposer; class IGraphicBufferProducer; class Layer; class MessageBase; class RefreshRateOverlay; class RegionSamplingThread; -class RenderArea; class TimeStats; class FrameTracer; class ScreenCapturer; @@ -165,6 +160,7 @@ class DisplaySurface; class OutputLayer; struct CompositionRefreshArgs; +class DisplayCreationArgsBuilder; } // namespace compositionengine namespace renderengine { @@ -201,9 +197,6 @@ enum class LatchUnsignaledConfig { Always, }; -struct DisplayRenderAreaBuilder; -struct LayerRenderAreaBuilder; - using DisplayColorSetting = compositionengine::OutputColorSetting; class SurfaceFlinger : public BnSurfaceComposer, @@ -219,11 +212,9 @@ public: SurfaceFlinger(surfaceflinger::Factory&, SkipInitializationTag) ANDROID_API; explicit SurfaceFlinger(surfaceflinger::Factory&) ANDROID_API; - // set main thread scheduling policy - static status_t setSchedFifo(bool enabled) ANDROID_API; - - // set main thread scheduling attributes - static status_t setSchedAttr(bool enabled); + // Set scheduling policy and attributes of main thread. + static void setSchedFifo(bool enabled, const char* whence); + static void setSchedAttr(bool enabled, const char* whence); static char const* getServiceName() ANDROID_API { return "SurfaceFlinger"; } @@ -248,6 +239,11 @@ public: // ISurfaceComposer.getMaxAcquiredBufferCount(). static int64_t minAcquiredBuffers; + // Controls the maximum acquired buffers SurfaceFlinger will suggest via + // ISurfaceComposer.getMaxAcquiredBufferCount(). + // Value is set through ro.surface_flinger.max_acquired_buffers. + static std::optional<int64_t> maxAcquiredBuffersOpt; + // Controls the maximum width and height in pixels that the graphics pipeline can support for // GPU fallback composition. For example, 8k devices with 4k GPUs, or 4k devices with 2k GPUs. static uint32_t maxGraphicsWidth; @@ -354,9 +350,6 @@ protected: // We're reference counted, never destroy SurfaceFlinger directly virtual ~SurfaceFlinger(); - virtual void processDisplayAdded(const wp<IBinder>& displayToken, const DisplayDeviceState&) - REQUIRES(mStateLock); - virtual std::shared_ptr<renderengine::ExternalTexture> getExternalTextureFromBufferData( BufferData& bufferData, const char* layerName, uint64_t transactionId); @@ -378,9 +371,7 @@ private: friend class Layer; friend class RefreshRateOverlay; friend class RegionSamplingThread; - friend class LayerRenderArea; friend class SurfaceComposerAIDL; - friend class DisplayRenderArea; // For unit tests friend class TestableSurfaceFlinger; @@ -389,7 +380,6 @@ private: using TransactionSchedule = scheduler::TransactionSchedule; using GetLayerSnapshotsFunction = std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>; - using RenderAreaBuilderVariant = std::variant<DisplayRenderAreaBuilder, LayerRenderAreaBuilder>; using DumpArgs = Vector<String16>; using Dumper = std::function<void(const DumpArgs&, bool asProto, std::string&)>; @@ -545,6 +535,7 @@ private: // ISurfaceComposer implementation: sp<IBinder> createVirtualDisplay(const std::string& displayName, bool isSecure, + gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy, const std::string& uniqueId, float requestedRefreshRate = 0.0f); status_t destroyVirtualDisplay(const sp<IBinder>& displayToken); @@ -554,13 +545,7 @@ private: } sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const; - status_t setTransactionState( - const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, - Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, - bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, - bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, - uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) override; + status_t setTransactionState(TransactionState&&) override; void bootFinished(); status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const; sp<IDisplayEventConnection> createDisplayEventConnection( @@ -743,8 +728,24 @@ private: void applyActiveMode(PhysicalDisplayId) REQUIRES(kMainThreadContext); // Called on the main thread in response to setPowerMode() - void setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) + void setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) REQUIRES(mStateLock, kMainThreadContext); + void setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) + REQUIRES(mStateLock, kMainThreadContext); + + // Returns whether to optimize globally for performance instead of power. + bool shouldOptimizeForPerformance() REQUIRES(mStateLock); + + // Turns on power optimizations, for example when there are no displays to be optimized for + // performance. + static void enablePowerOptimizations(const char* whence); + + // Turns off power optimizations. + static void disablePowerOptimizations(const char* whence); + + // Enables or disables power optimizations depending on whether there are displays that should + // be optimized for performance. + void applyOptimizationPolicy(const char* whence) REQUIRES(mStateLock); // Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that // display. Falls back to the display's defaultModeId otherwise. @@ -791,7 +792,7 @@ private: */ bool applyTransactionState(const FrameTimelineInfo& info, std::vector<ResolvedComposerState>& state, - Vector<DisplayState>& displays, uint32_t flags, + std::span<DisplayState> displays, uint32_t flags, const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<uint64_t>& uncacheBufferIds, @@ -852,6 +853,9 @@ private: status_t createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* outHandle, sp<Layer>* outLayer); + // Checks if there are layer leaks before creating layer + status_t checkLayerLeaks(); + status_t mirrorLayer(const LayerCreationArgs& args, const sp<IBinder>& mirrorFromHandle, gui::CreateSurfaceResult& outResult); @@ -872,31 +876,76 @@ private: using OutputCompositionState = compositionengine::impl::OutputCompositionState; - std::optional<OutputCompositionState> getSnapshotsFromMainThread( - RenderAreaBuilderVariant& renderAreaBuilder, - GetLayerSnapshotsFunction getLayerSnapshotsFn, - std::vector<std::pair<Layer*, sp<LayerFE>>>& layers); + /* + * Parameters used across screenshot methods. + */ + struct ScreenshotArgs { + // Contains the sequence ID of the parent layer if the screenshot is + // initiated though captureLayers(), or the display that the render + // result will be on if initiated through captureDisplay() + std::variant<int32_t, wp<const DisplayDevice>> captureTypeVariant; + + // Display ID of the display the result will be on + ftl::Optional<DisplayIdVariant> displayIdVariant{std::nullopt}; + + // If true, transform is inverted from the parent layer snapshot + bool childrenOnly{false}; - void captureScreenCommon(RenderAreaBuilderVariant, GetLayerSnapshotsFunction, - ui::Size bufferSize, ui::PixelFormat, bool allowProtected, - bool grayscale, const sp<IScreenCaptureListener>&); + // Source crop of the render area + Rect sourceCrop; - std::optional<OutputCompositionState> getDisplayStateFromRenderAreaBuilder( - RenderAreaBuilderVariant& renderAreaBuilder) REQUIRES(kMainThreadContext); + // Transform to be applied on the layers to transform them + // into the logical render area + ui::Transform transform; + + // Size of the physical render area + ui::Size reqSize; + + // Composition dataspace of the render area + ui::Dataspace dataspace; + + // If false, the secure layer is blacked out or skipped + // when rendered to an insecure render area + bool isSecure{false}; + + // If true, the render result may be used for system animations + // that must preserve the exact colors of the display + bool seamlessTransition{false}; + + // Current display brightness of the output composition state + float displayBrightnessNits{-1.f}; + + // SDR white point of the output composition state + float sdrWhitePointNits{-1.f}; + + // Current active color mode of the output composition state + ui::ColorMode colorMode{ui::ColorMode::NATIVE}; + + // Current active render intent of the output composition state + ui::RenderIntent renderIntent{ui::RenderIntent::COLORIMETRIC}; + }; + + bool getSnapshotsFromMainThread(ScreenshotArgs& args, + GetLayerSnapshotsFunction getLayerSnapshotsFn, + std::vector<std::pair<Layer*, sp<LayerFE>>>& layers); + + void captureScreenCommon(ScreenshotArgs& args, GetLayerSnapshotsFunction, ui::Size bufferSize, + ui::PixelFormat, bool allowProtected, bool grayscale, + const sp<IScreenCaptureListener>&); + + bool getDisplayStateOnMainThread(ScreenshotArgs& args) REQUIRES(kMainThreadContext); ftl::SharedFuture<FenceResult> captureScreenshot( - const RenderAreaBuilderVariant& renderAreaBuilder, - const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener, - const std::optional<OutputCompositionState>& displayState, + ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer, + bool regionSampling, bool grayscale, bool isProtected, + const sp<IScreenCaptureListener>& captureListener, const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers, const std::shared_ptr<renderengine::ExternalTexture>& hdrBuffer = nullptr, const std::shared_ptr<renderengine::ExternalTexture>& gainmapBuffer = nullptr); ftl::SharedFuture<FenceResult> renderScreenImpl( - const RenderArea*, const std::shared_ptr<renderengine::ExternalTexture>&, + ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults&, - const std::optional<OutputCompositionState>& displayState, const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers); void readPersistentProperties(); @@ -991,10 +1040,10 @@ private: // region of all screens presenting this layer stack. void invalidateLayerStack(const ui::LayerFilter& layerFilter, const Region& dirty); - ui::LayerFilter makeLayerFilterForDisplay(DisplayId displayId, ui::LayerStack layerStack) + ui::LayerFilter makeLayerFilterForDisplay(DisplayIdVariant displayId, ui::LayerStack layerStack) REQUIRES(mStateLock) { return {layerStack, - PhysicalDisplayId::tryCast(displayId) + asPhysicalDisplayId(displayId) .and_then(display::getPhysicalDisplay(mPhysicalDisplays)) .transform(&display::PhysicalDisplay::isInternal) .value_or(false)}; @@ -1033,7 +1082,8 @@ private: // Returns the active mode ID, or nullopt on hotplug failure. std::optional<DisplayModeId> processHotplugConnect(PhysicalDisplayId, hal::HWDisplayId, DisplayIdentificationInfo&&, - const char* displayString) + const char* displayString, + HWComposer::HotplugEvent event) REQUIRES(mStateLock, kMainThreadContext); void processHotplugDisconnect(PhysicalDisplayId, const char* displayString) REQUIRES(mStateLock, kMainThreadContext); @@ -1045,6 +1095,8 @@ private: const sp<compositionengine::DisplaySurface>& displaySurface, const sp<IGraphicBufferProducer>& producer) REQUIRES(mStateLock); void processDisplayChangesLocked() REQUIRES(mStateLock, kMainThreadContext); + void processDisplayAdded(const wp<IBinder>& displayToken, const DisplayDeviceState&) + REQUIRES(mStateLock, kMainThreadContext); void processDisplayRemoved(const wp<IBinder>& displayToken) REQUIRES(mStateLock, kMainThreadContext); void processDisplayChanged(const wp<IBinder>& displayToken, @@ -1084,8 +1136,10 @@ private: void enableHalVirtualDisplays(bool); // Virtual display lifecycle for ID generation and HAL allocation. - VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat, const std::string& uniqueId) - REQUIRES(mStateLock); + std::optional<VirtualDisplayIdVariant> acquireVirtualDisplay( + ui::Size, ui::PixelFormat, const std::string& uniqueId, + compositionengine::DisplayCreationArgsBuilder&) REQUIRES(mStateLock); + template <typename ID> void acquireVirtualDisplaySnapshot(ID displayId, const std::string& uniqueId) { std::lock_guard lock(mVirtualDisplaysMutex); @@ -1096,7 +1150,7 @@ private: } } - void releaseVirtualDisplay(VirtualDisplayId); + void releaseVirtualDisplay(VirtualDisplayIdVariant displayId); void releaseVirtualDisplaySnapshot(VirtualDisplayId displayId); // Returns a display other than `mActiveDisplayId` that can be activated, if any. @@ -1181,7 +1235,7 @@ private: bool isHdrLayer(const frontend::LayerSnapshot& snapshot) const; - ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const + ui::Rotation getPhysicalDisplayOrientation(PhysicalDisplayId, bool isPrimary) const REQUIRES(mStateLock); void traverseLegacyLayers(const LayerVector::Visitor& visitor) const REQUIRES(kMainThreadContext); @@ -1282,7 +1336,7 @@ private: struct HotplugEvent { hal::HWDisplayId hwcDisplayId; - hal::Connection connection = hal::Connection::INVALID; + HWComposer::HotplugEvent event; }; bool mIsHdcpViaNegVsync = false; @@ -1368,6 +1422,7 @@ private: std::atomic<int> mNumTrustedPresentationListeners = 0; std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine; + std::unique_ptr<HWComposer> mHWComposer; CompositionCoveragePerDisplay mCompositionCoverage; @@ -1527,9 +1582,11 @@ public: const sp<IBinder>& layerHandle, sp<gui::IDisplayEventConnection>* outConnection) override; binder::Status createConnection(sp<gui::ISurfaceComposerClient>* outClient) override; - binder::Status createVirtualDisplay(const std::string& displayName, bool isSecure, - const std::string& uniqueId, float requestedRefreshRate, - sp<IBinder>* outDisplay) override; + binder::Status createVirtualDisplay( + const std::string& displayName, bool isSecure, + gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy, + const std::string& uniqueId, float requestedRefreshRate, + sp<IBinder>* outDisplay) override; binder::Status destroyVirtualDisplay(const sp<IBinder>& displayToken) override; binder::Status getPhysicalDisplayIds(std::vector<int64_t>* outDisplayIds) override; binder::Status getPhysicalDisplayToken(int64_t displayId, sp<IBinder>* outDisplay) override; diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp index 2676ca6777..6bbc04cf6f 100644 --- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp +++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp @@ -139,7 +139,8 @@ perfetto::protos::LayerState TransactionProtoParser::toProto( colorProto->set_b(layer.color.b); } if (layer.what & layer_state_t::eTransparentRegionChanged) { - LayerProtoHelper::writeToProto(layer.transparentRegion, proto.mutable_transparent_region()); + LayerProtoHelper::writeToProto(layer.getTransparentRegion(), + proto.mutable_transparent_region()); } if (layer.what & layer_state_t::eBufferTransformChanged) { proto.set_transform(layer.bufferTransform); @@ -191,33 +192,30 @@ perfetto::protos::LayerState TransactionProtoParser::toProto( } if (layer.what & layer_state_t::eInputInfoChanged) { - if (layer.windowInfoHandle) { - const gui::WindowInfo* inputInfo = layer.windowInfoHandle->getInfo(); - perfetto::protos::LayerState_WindowInfo* windowInfoProto = - proto.mutable_window_info_handle(); - windowInfoProto->set_layout_params_flags(inputInfo->layoutParamsFlags.get()); - windowInfoProto->set_layout_params_type( - static_cast<int32_t>(inputInfo->layoutParamsType)); - windowInfoProto->set_input_config(inputInfo->inputConfig.get()); - LayerProtoHelper::writeToProto(inputInfo->touchableRegion, - windowInfoProto->mutable_touchable_region()); - windowInfoProto->set_surface_inset(inputInfo->surfaceInset); - windowInfoProto->set_focusable( - !inputInfo->inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE)); - windowInfoProto->set_has_wallpaper(inputInfo->inputConfig.test( - gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)); - windowInfoProto->set_global_scale_factor(inputInfo->globalScaleFactor); - perfetto::protos::Transform* transformProto = windowInfoProto->mutable_transform(); - transformProto->set_dsdx(inputInfo->transform.dsdx()); - transformProto->set_dtdx(inputInfo->transform.dtdx()); - transformProto->set_dtdy(inputInfo->transform.dtdy()); - transformProto->set_dsdy(inputInfo->transform.dsdy()); - transformProto->set_tx(inputInfo->transform.tx()); - transformProto->set_ty(inputInfo->transform.ty()); - windowInfoProto->set_replace_touchable_region_with_crop( - inputInfo->replaceTouchableRegionWithCrop); - windowInfoProto->set_crop_layer_id(resolvedComposerState.touchCropId); - } + const gui::WindowInfo* inputInfo = &layer.getWindowInfo(); + perfetto::protos::LayerState_WindowInfo* windowInfoProto = + proto.mutable_window_info_handle(); + windowInfoProto->set_layout_params_flags(inputInfo->layoutParamsFlags.get()); + windowInfoProto->set_layout_params_type(static_cast<int32_t>(inputInfo->layoutParamsType)); + windowInfoProto->set_input_config(inputInfo->inputConfig.get()); + LayerProtoHelper::writeToProto(inputInfo->touchableRegion, + windowInfoProto->mutable_touchable_region()); + windowInfoProto->set_surface_inset(inputInfo->surfaceInset); + windowInfoProto->set_focusable( + !inputInfo->inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE)); + windowInfoProto->set_has_wallpaper(inputInfo->inputConfig.test( + gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)); + windowInfoProto->set_global_scale_factor(inputInfo->globalScaleFactor); + perfetto::protos::Transform* transformProto = windowInfoProto->mutable_transform(); + transformProto->set_dsdx(inputInfo->transform.dsdx()); + transformProto->set_dtdx(inputInfo->transform.dtdx()); + transformProto->set_dtdy(inputInfo->transform.dtdy()); + transformProto->set_dsdy(inputInfo->transform.dsdy()); + transformProto->set_tx(inputInfo->transform.tx()); + transformProto->set_ty(inputInfo->transform.ty()); + windowInfoProto->set_replace_touchable_region_with_crop( + inputInfo->replaceTouchableRegionWithCrop); + windowInfoProto->set_crop_layer_id(resolvedComposerState.touchCropId); } if (layer.what & layer_state_t::eBackgroundColorChanged) { proto.set_bg_color_alpha(layer.bgColor.a); @@ -323,7 +321,7 @@ QueuedTransactionState TransactionProtoParser::fromProto( int32_t displayCount = proto.display_changes_size(); t.displays.reserve(static_cast<size_t>(displayCount)); for (int i = 0; i < displayCount; i++) { - t.displays.add(fromProto(proto.display_changes(i))); + t.displays.emplace_back(fromProto(proto.display_changes(i))); } return t; } @@ -410,7 +408,9 @@ void TransactionProtoParser::fromProto(const perfetto::protos::LayerState& proto layer.color.b = colorProto.b(); } if (proto.what() & layer_state_t::eTransparentRegionChanged) { - LayerProtoHelper::readFromProto(proto.transparent_region(), layer.transparentRegion); + Region transparentRegion; + LayerProtoHelper::readFromProto(proto.transparent_region(), transparentRegion); + layer.updateTransparentRegion(transparentRegion); } if (proto.what() & layer_state_t::eBufferTransformChanged) { layer.bufferTransform = proto.transform(); @@ -486,7 +486,7 @@ void TransactionProtoParser::fromProto(const perfetto::protos::LayerState& proto windowInfoProto.replace_touchable_region_with_crop(); resolvedComposerState.touchCropId = windowInfoProto.crop_layer_id(); - layer.windowInfoHandle = sp<gui::WindowInfoHandle>::make(inputInfo); + *layer.editWindowInfo() = inputInfo; } if (proto.what() & layer_state_t::eBackgroundColorChanged) { layer.bgColor.a = proto.bg_color_alpha(); diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp index 5cf42449c0..84d837c37a 100644 --- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp +++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp @@ -102,11 +102,10 @@ bool LayerTraceGenerator::generate(const perfetto::protos::TransactionTraceFile& QueuedTransactionState transaction = parser.fromProto(entry.transactions(j)); for (auto& resolvedComposerState : transaction.states) { if (resolvedComposerState.state.what & layer_state_t::eInputInfoChanged) { - if (!resolvedComposerState.state.windowInfoHandle->getInfo()->inputConfig.test( + if (!resolvedComposerState.state.getWindowInfo().inputConfig.test( gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL)) { // create a fake token since the FE expects a valid token - resolvedComposerState.state.windowInfoHandle->editInfo()->token = - sp<BBinder>::make(); + resolvedComposerState.state.editWindowInfo()->token = sp<BBinder>::make(); } } } diff --git a/services/surfaceflinger/common/Android.bp b/services/surfaceflinger/common/Android.bp index 8786f6e592..13f65770cd 100644 --- a/services/surfaceflinger/common/Android.bp +++ b/services/surfaceflinger/common/Android.bp @@ -16,9 +16,9 @@ cc_defaults { ], shared_libs: [ "libSurfaceFlingerProp", - "server_configurable_flags", "libaconfig_storage_read_api_cc", "libtracing_perfetto", + "server_configurable_flags", ], static_libs: [ "librenderengine_includes", @@ -37,11 +37,12 @@ cc_library_static { "libsurfaceflinger_common_defaults", ], static_libs: [ - "libsurfaceflingerflags", "aconfig_hardware_flags_c_lib", + "android.companion.virtualdevice.flags-aconfig-cc", "android.os.flags-aconfig-cc", "android.server.display.flags-aconfig-cc", "libguiflags_no_apex", + "libsurfaceflingerflags", ], } @@ -51,44 +52,47 @@ cc_library_static { "libsurfaceflinger_common_defaults", ], static_libs: [ - "libsurfaceflingerflags_test", "aconfig_hardware_flags_c_lib", + "android.companion.virtualdevice.flags-aconfig-cc", "android.os.flags-aconfig-cc-test", "android.server.display.flags-aconfig-cc", "libguiflags_no_apex", + "libsurfaceflingerflags_test", ], } cc_defaults { name: "libsurfaceflinger_common_deps", shared_libs: [ - "server_configurable_flags", "libaconfig_storage_read_api_cc", "libtracing_perfetto", + "server_configurable_flags", ], static_libs: [ - "libsurfaceflinger_common", - "libsurfaceflingerflags", "aconfig_hardware_flags_c_lib", + "android.companion.virtualdevice.flags-aconfig-cc", "android.os.flags-aconfig-cc", "android.server.display.flags-aconfig-cc", "libguiflags_no_apex", + "libsurfaceflinger_common", + "libsurfaceflingerflags", ], } cc_defaults { name: "libsurfaceflinger_common_test_deps", shared_libs: [ - "server_configurable_flags", "libaconfig_storage_read_api_cc", "libtracing_perfetto", + "server_configurable_flags", ], static_libs: [ - "libsurfaceflinger_common_test", - "libsurfaceflingerflags_test", "aconfig_hardware_flags_c_lib", + "android.companion.virtualdevice.flags-aconfig-cc", "android.os.flags-aconfig-cc-test", "android.server.display.flags-aconfig-cc", "libguiflags_no_apex", + "libsurfaceflinger_common_test", + "libsurfaceflingerflags_test", ], } diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp index e80cd78cbd..5ff3d821f7 100644 --- a/services/surfaceflinger/common/FlagManager.cpp +++ b/services/surfaceflinger/common/FlagManager.cpp @@ -26,8 +26,9 @@ #include <server_configurable_flags/get_flags.h> #include <cinttypes> -#include <android_os.h> +#include <android_companion_virtualdevice_flags.h> #include <android_hardware_flags.h> +#include <android_os.h> #include <com_android_graphics_libgui_flags.h> #include <com_android_graphics_surfaceflinger_flags.h> #include <com_android_server_display_feature_flags.h> @@ -104,9 +105,19 @@ void FlagManager::dump(std::string& result) const { dumpFlag(result, (aconfig), #name, std::bind(&FlagManager::name, this)) #define DUMP_LEGACY_SERVER_FLAG(name) DUMP_FLAG_INTERNAL(name, false) #define DUMP_ACONFIG_FLAG(name) DUMP_FLAG_INTERNAL(name, true) +#define DUMP_SYSPROP_FLAG(name) \ + dumpFlag(result, (true), "debug.sf." #name, std::bind(&FlagManager::name, this)) base::StringAppendF(&result, "FlagManager values: \n"); + /// Sysprop flags /// + DUMP_SYSPROP_FLAG(disable_sched_fifo_sf); + DUMP_SYSPROP_FLAG(disable_sched_fifo_sf_binder); + DUMP_SYSPROP_FLAG(disable_sched_fifo_sf_sched); + DUMP_SYSPROP_FLAG(disable_sched_fifo_re); + DUMP_SYSPROP_FLAG(disable_sched_fifo_composer); + DUMP_SYSPROP_FLAG(disable_sched_fifo_composer_callback); + /// Legacy server flags /// DUMP_LEGACY_SERVER_FLAG(use_adpf_cpu_hint); DUMP_LEGACY_SERVER_FLAG(use_skia_tracing); @@ -115,8 +126,11 @@ void FlagManager::dump(std::string& result) const { DUMP_ACONFIG_FLAG(adpf_gpu_sf); DUMP_ACONFIG_FLAG(adpf_native_session_manager); DUMP_ACONFIG_FLAG(adpf_use_fmq_channel); + DUMP_ACONFIG_FLAG(correct_virtual_display_power_state); DUMP_ACONFIG_FLAG(graphite_renderengine_preview_rollout); + DUMP_ACONFIG_FLAG(increase_missed_frame_jank_threshold); DUMP_ACONFIG_FLAG(refresh_rate_overlay_on_external_display); + DUMP_ACONFIG_FLAG(vsync_predictor_recovery); /// Trunk stable readonly flags /// /// IMPORTANT - please keep alphabetize to reduce merge conflicts @@ -127,7 +141,6 @@ void FlagManager::dump(std::string& result) const { DUMP_ACONFIG_FLAG(begone_bright_hlg); DUMP_ACONFIG_FLAG(cache_when_source_crop_layer_only_moved); DUMP_ACONFIG_FLAG(commit_not_composited); - DUMP_ACONFIG_FLAG(connected_display); DUMP_ACONFIG_FLAG(connected_display_hdr); DUMP_ACONFIG_FLAG(correct_dpi_with_display_size); DUMP_ACONFIG_FLAG(deprecate_frame_tracker); @@ -151,7 +164,6 @@ void FlagManager::dump(std::string& result) const { DUMP_ACONFIG_FLAG(latch_unsignaled_with_auto_refresh_changed); DUMP_ACONFIG_FLAG(local_tonemap_screenshots); DUMP_ACONFIG_FLAG(misc1); - DUMP_ACONFIG_FLAG(multithreaded_present); DUMP_ACONFIG_FLAG(no_vsyncs_on_screen_off); DUMP_ACONFIG_FLAG(override_trusted_overlay); DUMP_ACONFIG_FLAG(protected_if_client); @@ -160,6 +172,7 @@ void FlagManager::dump(std::string& result) const { DUMP_ACONFIG_FLAG(restore_blur_step); DUMP_ACONFIG_FLAG(skip_invisible_windows_in_input); DUMP_ACONFIG_FLAG(stable_edid_ids); + DUMP_ACONFIG_FLAG(synced_resolution_switch); DUMP_ACONFIG_FLAG(trace_frame_rate_override); DUMP_ACONFIG_FLAG(true_hdr_screenshots); DUMP_ACONFIG_FLAG(use_known_refresh_rate_for_fps_consistency); @@ -185,6 +198,12 @@ bool FlagManager::getServerConfigurableFlag(const char* experimentFlagName) cons const auto res = parseBool(value.c_str()); return res.has_value() && res.value(); } +#define FLAG_MANAGER_SYSPROP_FLAG(name, defaultVal) \ + bool FlagManager::name() const { \ + static const bool kFlagValue = \ + base::GetBoolProperty("debug.sf." #name, /* default value*/ defaultVal); \ + return kFlagValue; \ + } #define FLAG_MANAGER_LEGACY_SERVER_FLAG(name, syspropOverride, serverFlagName) \ bool FlagManager::name() const { \ @@ -215,6 +234,14 @@ bool FlagManager::getServerConfigurableFlag(const char* experimentFlagName) cons #define FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(name, syspropOverride, owner) \ FLAG_MANAGER_ACONFIG_INTERNAL(name, syspropOverride, owner) +/// Debug sysprop flags - default value is always false /// +FLAG_MANAGER_SYSPROP_FLAG(disable_sched_fifo_sf, /* default */ false) +FLAG_MANAGER_SYSPROP_FLAG(disable_sched_fifo_sf_binder, /* default */ false) +FLAG_MANAGER_SYSPROP_FLAG(disable_sched_fifo_sf_sched, /* default */ false) +FLAG_MANAGER_SYSPROP_FLAG(disable_sched_fifo_re, /* default */ false) +FLAG_MANAGER_SYSPROP_FLAG(disable_sched_fifo_composer, /* default */ false) +FLAG_MANAGER_SYSPROP_FLAG(disable_sched_fifo_composer_callback, /* default */ false) + /// Legacy server flags /// FLAG_MANAGER_LEGACY_SERVER_FLAG(test_flag, "", "") FLAG_MANAGER_LEGACY_SERVER_FLAG(use_adpf_cpu_hint, "debug.sf.enable_adpf_cpu_hint", @@ -225,14 +252,12 @@ FLAG_MANAGER_LEGACY_SERVER_FLAG(use_skia_tracing, PROPERTY_SKIA_ATRACE_ENABLED, /// Trunk stable readonly flags /// FLAG_MANAGER_ACONFIG_FLAG(adpf_fmq_sf, "") FLAG_MANAGER_ACONFIG_FLAG(arr_setframerate_gte_enum, "debug.sf.arr_setframerate_gte_enum") -FLAG_MANAGER_ACONFIG_FLAG(connected_display, "") FLAG_MANAGER_ACONFIG_FLAG(enable_small_area_detection, "") FLAG_MANAGER_ACONFIG_FLAG(stable_edid_ids, "debug.sf.stable_edid_ids") FLAG_MANAGER_ACONFIG_FLAG(frame_rate_category_mrr, "debug.sf.frame_rate_category_mrr") FLAG_MANAGER_ACONFIG_FLAG(misc1, "") FLAG_MANAGER_ACONFIG_FLAG(vrr_config, "debug.sf.enable_vrr_config") FLAG_MANAGER_ACONFIG_FLAG(hdcp_level_hal, "") -FLAG_MANAGER_ACONFIG_FLAG(multithreaded_present, "debug.sf.multithreaded_present") FLAG_MANAGER_ACONFIG_FLAG(add_sf_skipped_frames_to_trace, "") FLAG_MANAGER_ACONFIG_FLAG(use_known_refresh_rate_for_fps_consistency, "") FLAG_MANAGER_ACONFIG_FLAG(cache_when_source_crop_layer_only_moved, @@ -270,15 +295,20 @@ FLAG_MANAGER_ACONFIG_FLAG(skip_invisible_windows_in_input, ""); FLAG_MANAGER_ACONFIG_FLAG(begone_bright_hlg, "debug.sf.begone_bright_hlg"); FLAG_MANAGER_ACONFIG_FLAG(window_blur_kawase2, ""); FLAG_MANAGER_ACONFIG_FLAG(reject_dupe_layerstacks, ""); +FLAG_MANAGER_ACONFIG_FLAG(synced_resolution_switch, ""); /// Trunk stable server (R/W) flags /// FLAG_MANAGER_ACONFIG_FLAG(refresh_rate_overlay_on_external_display, "") FLAG_MANAGER_ACONFIG_FLAG(adpf_gpu_sf, "") FLAG_MANAGER_ACONFIG_FLAG(adpf_native_session_manager, ""); FLAG_MANAGER_ACONFIG_FLAG(graphite_renderengine_preview_rollout, ""); +FLAG_MANAGER_ACONFIG_FLAG(increase_missed_frame_jank_threshold, ""); +FLAG_MANAGER_ACONFIG_FLAG(vsync_predictor_recovery, ""); /// Trunk stable server (R/W) flags from outside SurfaceFlinger /// FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(adpf_use_fmq_channel, "", android::os) +FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(correct_virtual_display_power_state, "", + android::companion::virtualdevice::flags) /// Trunk stable readonly flags from outside SurfaceFlinger /// FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(idle_screen_refresh_rate_timeout, "", diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h index c7f97b4008..419e92b952 100644 --- a/services/surfaceflinger/common/include/common/FlagManager.h +++ b/services/surfaceflinger/common/include/common/FlagManager.h @@ -42,6 +42,14 @@ public: void setUnitTestMode(); + /// Debug sysprop flags /// + bool disable_sched_fifo_sf() const; + bool disable_sched_fifo_sf_binder() const; + bool disable_sched_fifo_sf_sched() const; + bool disable_sched_fifo_re() const; + bool disable_sched_fifo_composer() const; + bool disable_sched_fifo_composer_callback() const; + /// Legacy server flags /// bool test_flag() const; bool use_adpf_cpu_hint() const; @@ -52,8 +60,11 @@ public: bool adpf_native_session_manager() const; bool adpf_use_fmq_channel() const; bool adpf_use_fmq_channel_fixed() const; + bool correct_virtual_display_power_state() const; bool graphite_renderengine_preview_rollout() const; + bool increase_missed_frame_jank_threshold() const; bool refresh_rate_overlay_on_external_display() const; + bool vsync_predictor_recovery() const; /// Trunk stable readonly flags /// /// IMPORTANT - please keep alphabetize to reduce merge conflicts @@ -64,7 +75,6 @@ public: bool begone_bright_hlg() const; bool cache_when_source_crop_layer_only_moved() const; bool commit_not_composited() const; - bool connected_display() const; bool connected_display_hdr() const; bool correct_dpi_with_display_size() const; bool deprecate_frame_tracker() const; @@ -89,7 +99,6 @@ public: bool local_tonemap_screenshots() const; bool luts_api() const; bool misc1() const; - bool multithreaded_present() const; bool no_vsyncs_on_screen_off() const; bool override_trusted_overlay() const; bool protected_if_client() const; @@ -98,6 +107,7 @@ public: bool restore_blur_step() const; bool skip_invisible_windows_in_input() const; bool stable_edid_ids() const; + bool synced_resolution_switch() const; bool trace_frame_rate_override() const; bool true_hdr_screenshots() const; bool use_known_refresh_rate_for_fps_consistency() const; diff --git a/services/surfaceflinger/common/include/common/WorkloadTracer.h b/services/surfaceflinger/common/include/common/WorkloadTracer.h new file mode 100644 index 0000000000..c4074f72ff --- /dev/null +++ b/services/surfaceflinger/common/include/common/WorkloadTracer.h @@ -0,0 +1,29 @@ + +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <ftl/flags.h> +#include <stdint.h> +namespace android::WorkloadTracer { + +static constexpr int32_t COMPOSITION_TRACE_COOKIE = 1; +static constexpr int32_t POST_COMPOSITION_TRACE_COOKIE = 2; +static constexpr size_t COMPOSITION_SUMMARY_SIZE = 64; +static constexpr const char* TRACK_NAME = "CriticalWorkload"; + +} // namespace android::WorkloadTracer
\ No newline at end of file diff --git a/services/surfaceflinger/common/include/common/trace.h b/services/surfaceflinger/common/include/common/trace.h index dc5716ba05..9a7e97feba 100644 --- a/services/surfaceflinger/common/include/common/trace.h +++ b/services/surfaceflinger/common/include/common/trace.h @@ -65,6 +65,8 @@ #define SFTRACE_NAME(name) ::android::ScopedTrace PASTE(___tracer, __LINE__)(name) // SFTRACE_CALL is an SFTRACE_NAME that uses the current function name. #define SFTRACE_CALL() SFTRACE_NAME(__FUNCTION__) +#define SFTRACE_NAME_FOR_TRACK(trackName, name) \ + ::android::ScopedTraceForTrack PASTE(___tracer, __LINE__)(trackName, name) #define SFTRACE_FORMAT(fmt, ...) \ ::android::ScopedTrace PASTE(___tracer, __LINE__)(fmt, ##__VA_ARGS__) @@ -87,4 +89,21 @@ public: inline ~ScopedTrace() { SFTRACE_END(); } }; +class ScopedTraceForTrack { +public: + inline ScopedTraceForTrack(const char* trackName, const char* name) + : mCookie(getUniqueCookie()), mTrackName(trackName) { + SFTRACE_ASYNC_FOR_TRACK_BEGIN(mTrackName, name, mCookie); + } + inline ~ScopedTraceForTrack() { SFTRACE_ASYNC_FOR_TRACK_END(mTrackName, mCookie); } + +private: + static int32_t getUniqueCookie() { + static std::atomic<int32_t> sUniqueCookie = 1000; + return sUniqueCookie++; + } + int32_t mCookie; + const char* mTrackName; +}; + } // namespace android diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp index 6c8972f1fb..4afcd00ecb 100644 --- a/services/surfaceflinger/main_surfaceflinger.cpp +++ b/services/surfaceflinger/main_surfaceflinger.cpp @@ -77,7 +77,7 @@ static void startDisplayService() { } } -int main(int, char**) { +int main() { signal(SIGPIPE, SIG_IGN); hardware::configureRpcThreadpool(1 /* maxThreads */, @@ -91,9 +91,7 @@ int main(int, char**) { // Set uclamp.min setting on all threads, maybe an overkill but we want // to cover important threads like RenderEngine. - if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) { - ALOGW("Failed to set uclamp.min during boot: %s", strerror(errno)); - } + SurfaceFlinger::setSchedAttr(true, __func__); // The binder threadpool we start will inherit sched policy and priority // of (this) creating thread. We want the binder thread pool to have @@ -132,7 +130,8 @@ int main(int, char**) { // Set the minimum policy of surfaceflinger node to be SCHED_FIFO. // So any thread with policy/priority lower than {SCHED_FIFO, 1}, will run // at least with SCHED_FIFO policy and priority 1. - if (errorInPriorityModification == 0) { + if (errorInPriorityModification == 0 && + !FlagManager::getInstance().disable_sched_fifo_sf_binder()) { flinger->setMinSchedulerPolicy(SCHED_FIFO, newPriority); } @@ -150,7 +149,8 @@ int main(int, char**) { // publish gui::ISurfaceComposer, the new AIDL interface sp<SurfaceComposerAIDL> composerAIDL = sp<SurfaceComposerAIDL>::make(flinger); - if (FlagManager::getInstance().misc1()) { + if (FlagManager::getInstance().misc1() && + !FlagManager::getInstance().disable_sched_fifo_composer()) { composerAIDL->setMinSchedulerPolicy(SCHED_FIFO, newPriority); } sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false, @@ -158,14 +158,8 @@ int main(int, char**) { startDisplayService(); // dependency on SF getting registered above - if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) { - ALOGW("Failed to set SCHED_FIFO during boot: %s", strerror(errno)); - } - - // run surface flinger in this thread + SurfaceFlinger::setSchedFifo(true, __func__); flinger->run(); - - return 0; } // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig index b28d2697c5..d8f51fe7e4 100644 --- a/services/surfaceflinger/surfaceflinger_flags_new.aconfig +++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig @@ -190,6 +190,13 @@ flag { } # graphite_renderengine_preview_rollout flag { + name: "increase_missed_frame_jank_threshold" + namespace: "core_graphics" + description: "Increase the jank threshold to 4 milliseconds" + bug: "342265411" +} # increase_missed_frame_jank_threshold + +flag { name: "latch_unsignaled_with_auto_refresh_changed" namespace: "core_graphics" description: "Ignore eAutoRefreshChanged with latch unsignaled" @@ -258,6 +265,13 @@ flag { } # stable_edid_ids flag { + name: "synced_resolution_switch" + namespace: "core_graphics" + description: "Synchronize resolution modeset with framebuffer resizing" + bug: "355427258" +} # synced_resolution_switch + +flag { name: "true_hdr_screenshots" namespace: "core_graphics" description: "Enables screenshotting display content in HDR, sans tone mapping" @@ -307,6 +321,16 @@ flag { } # vrr_bugfix_dropped_frame flag { + name: "vsync_predictor_recovery" + namespace: "core_graphics" + description: "Recover the vsync predictor from bad vsync model" + bug: "385059265" + metadata { + purpose: PURPOSE_BUGFIX + } + } # vsync_predictor_recovery + +flag { name: "window_blur_kawase2" namespace: "core_graphics" description: "Flag for using Kawase2 algorithm for window blur" diff --git a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop index 0ad5ac9956..bfafb655d9 100644 --- a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop +++ b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop @@ -483,6 +483,16 @@ prop { prop_name: "ro.surface_flinger.min_acquired_buffers" } +# Defines the maximum acquired buffers SurfaceFlinger will suggest via +# ISurfaceComposer.getMaxAcquiredBufferCount(). +prop { + api_name: "max_acquired_buffers" + type: Long + scope: Public + access: Readonly + prop_name: "ro.surface_flinger.max_acquired_buffers" +} + # When enabled, SurfaceFlinger will attempt to clear the per-layer HAL buffer cache slots for # buffers when they are evicted from the app cache by using additional setLayerBuffer commands. # Ideally, this behavior would always be enabled to reduce graphics memory consumption. However, diff --git a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt index 00173009f5..e2ac233f6b 100644 --- a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt +++ b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt @@ -82,6 +82,11 @@ props { prop_name: "ro.surface_flinger.ignore_hdr_camera_layers" } prop { + api_name: "max_acquired_buffers" + type: Long + prop_name: "ro.surface_flinger.max_acquired_buffers" + } + prop { api_name: "max_frame_buffer_acquired_buffers" type: Long prop_name: "ro.surface_flinger.max_frame_buffer_acquired_buffers" diff --git a/services/surfaceflinger/tests/AndroidTest.xml b/services/surfaceflinger/tests/AndroidTest.xml index 000628f598..ad43cdcc5d 100644 --- a/services/surfaceflinger/tests/AndroidTest.xml +++ b/services/surfaceflinger/tests/AndroidTest.xml @@ -19,6 +19,9 @@ <option name="push" value="SurfaceFlinger_test->/data/local/tmp/SurfaceFlinger_test" /> </target_preparer> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/> + <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> + <option name="screen-always-on" value="on" /> + </target_preparer> <option name="test-suite-tag" value="apct" /> <test class="com.android.tradefed.testtype.GTest" > <option name="native-test-device-path" value="/data/local/tmp" /> diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp index b4496d3f1a..5a8291413c 100644 --- a/services/surfaceflinger/tests/LayerCallback_test.cpp +++ b/services/surfaceflinger/tests/LayerCallback_test.cpp @@ -147,7 +147,7 @@ public: << "Timeout waiting for vsync event"; DisplayEventReceiver::Event event; while (mDisplayEventReceiver.getEvents(&event, 1) > 0) { - if (event.header.type != DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { + if (event.header.type != DisplayEventType::DISPLAY_EVENT_VSYNC) { continue; } diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp index f247c9f088..151611cad2 100644 --- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp @@ -585,6 +585,83 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, ParentCornerRadiusTakesPrecedence) } } +TEST_P(LayerTypeAndRenderTypeTransactionTest, SetClientDrawnCornerRadius) { + sp<SurfaceControl> layer; + const uint8_t size = 64; + const uint8_t testArea = 4; + const float cornerRadius = 20.0f; + ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", size, size)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, size, size)); + + Transaction() + .setClientDrawnCornerRadius(layer, cornerRadius) + .setCornerRadius(layer, cornerRadius) + .setCrop(layer, Rect(size, size)) + .apply(); + + { + const uint8_t bottom = size - 1; + const uint8_t right = size - 1; + auto shot = getScreenCapture(); + // Solid corners + shot->expectColor(Rect(0, 0, testArea, testArea), Color::RED); + shot->expectColor(Rect(size - testArea, 0, right, testArea), Color::RED); + shot->expectColor(Rect(0, bottom - testArea, testArea, bottom), Color::RED); + shot->expectColor(Rect(size - testArea, bottom - testArea, right, bottom), Color::RED); + // Solid center + shot->expectColor(Rect(size / 2 - testArea / 2, size / 2 - testArea / 2, + size / 2 + testArea / 2, size / 2 + testArea / 2), + Color::RED); + } +} + +// Test if ParentCornerRadiusTakesPrecedence if the parent's client drawn corner radius crop +// is fully contained by the child corner radius crop. +TEST_P(LayerTypeAndRenderTypeTransactionTest, ParentCornerRadiusPrecedenceClientDrawnCornerRadius) { + sp<SurfaceControl> parent; + sp<SurfaceControl> child; + const uint32_t size = 64; + const uint32_t parentSize = size * 3; + const Rect parentCrop(size, size, size, size); + const uint32_t testLength = 4; + const float cornerRadius = 20.0f; + ASSERT_NO_FATAL_FAILURE(parent = createLayer("parent", parentSize, parentSize)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(parent, Color::RED, parentSize, parentSize)); + ASSERT_NO_FATAL_FAILURE(child = createLayer("child", size, size)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(child, Color::GREEN, size, size)); + + Transaction() + .setCornerRadius(parent, cornerRadius) + .setCrop(parent, parentCrop) + .setClientDrawnCornerRadius(parent, cornerRadius) + .reparent(child, parent) + .setPosition(child, size, size) + .apply(true); + + { + const uint32_t top = size; + const uint32_t left = size; + const uint32_t bottom = size * 2; + const uint32_t right = size * 2; + auto shot = getScreenCapture(); + // Corners are RED because parent's client drawn corner radius is actually 0 + // and the child is fully within the parent's crop + // TL + shot->expectColor(Rect(left, top, testLength, testLength), Color::RED); + // TR + shot->expectColor(Rect(right - testLength, top, testLength, testLength), Color::RED); + // BL + shot->expectColor(Rect(left, bottom - testLength, testLength, testLength), Color::RED); + // BR + shot->expectColor(Rect(right - testLength, bottom - testLength, testLength, testLength), + Color::RED); + // Solid center + shot->expectColor(Rect(parentSize / 2 - testLength, parentSize / 2 - testLength, testLength, + testLength), + Color::GREEN); + } +} + TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) { if (!deviceSupportsBlurs()) GTEST_SKIP(); if (!deviceUsesSkiaRenderEngine()) GTEST_SKIP(); diff --git a/services/surfaceflinger/tests/MultiDisplay_test.cpp b/services/surfaceflinger/tests/MultiDisplay_test.cpp index 54bb253526..cf6d3282a1 100644 --- a/services/surfaceflinger/tests/MultiDisplay_test.cpp +++ b/services/surfaceflinger/tests/MultiDisplay_test.cpp @@ -51,7 +51,7 @@ protected: mConsumer->setDefaultBufferSize(mMainDisplayMode.resolution.getWidth(), mMainDisplayMode.resolution.getHeight()); - class StubConsumerListener : public BnConsumerListener { + class StubConsumerListener : public IConsumerListener { virtual void onFrameAvailable(const BufferItem&) override {} virtual void onBuffersReleased() override {} virtual void onSidebandStreamChanged() override {} diff --git a/services/surfaceflinger/tests/TransactionTestHarnesses.h b/services/surfaceflinger/tests/TransactionTestHarnesses.h index c95c875746..c91f1ea760 100644 --- a/services/surfaceflinger/tests/TransactionTestHarnesses.h +++ b/services/surfaceflinger/tests/TransactionTestHarnesses.h @@ -48,7 +48,11 @@ public: ui::DisplayMode displayMode; SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode); - const ui::Size& resolution = displayMode.resolution; + ui::Size resolution = displayMode.resolution; + if (displayState.orientation == ui::Rotation::Rotation90 || + displayState.orientation == ui::Rotation::Rotation270) { + std::swap(resolution.width, resolution.height); + } sp<IBinder> vDisplay; @@ -93,8 +97,8 @@ public: #else t.setDisplaySurface(vDisplay, producer); #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) - t.setDisplayProjection(vDisplay, displayState.orientation, - Rect(displayState.layerStackSpaceRect), Rect(resolution)); + t.setDisplayProjection(vDisplay, ui::Rotation::Rotation0, Rect(resolution), + Rect(resolution)); t.setDisplayLayerStack(vDisplay, layerStack); t.setLayerStack(mirrorSc, layerStack); t.apply(); diff --git a/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp b/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp index 0925118f87..fec6242728 100644 --- a/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp +++ b/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp @@ -90,5 +90,46 @@ static void updateClientStatesNoChanges(benchmark::State& state) { } BENCHMARK(updateClientStatesNoChanges); +static void propagateManyHiddenChildren(benchmark::State& state) { + LayerLifecycleManager lifecycleManager; + LayerLifecycleManagerHelper helper(lifecycleManager); + + helper.createRootLayer(0); + for (uint32_t i = 1; i < 50; ++i) { + helper.createLayer(i, i - 1); + } + + helper.hideLayer(0); + + LayerHierarchyBuilder hierarchyBuilder; + DisplayInfo info; + info.info.logicalHeight = 100; + info.info.logicalWidth = 100; + DisplayInfos displayInfos; + displayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info); + ShadowSettings globalShadowSettings; + + LayerSnapshotBuilder snapshotBuilder; + + int i = 1; + for (auto _ : state) { + i++; + helper.setAlpha(0, (1 + (i % 255)) / 255.0f); + + if (lifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)) { + hierarchyBuilder.update(lifecycleManager); + } + LayerSnapshotBuilder::Args args{.root = hierarchyBuilder.getHierarchy(), + .layerLifecycleManager = lifecycleManager, + .displays = displayInfos, + .globalShadowSettings = globalShadowSettings, + .supportedLayerGenericMetadata = {}, + .genericLayerMetadataKeyMap = {}}; + snapshotBuilder.update(args); + lifecycleManager.commitChanges(); + } +} +BENCHMARK(propagateManyHiddenChildren); + } // namespace } // namespace android::surfaceflinger diff --git a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h index a894c418f6..82390ac6f3 100644 --- a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h +++ b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h @@ -265,9 +265,8 @@ public: transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged; transactions.back().states.front().layerId = id; - transactions.back().states.front().state.windowInfoHandle = - sp<gui::WindowInfoHandle>::make(); - auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo(); + auto inputInfo = transactions.back().states.front().state.editWindowInfo(); + *inputInfo = {}; inputInfo->touchableRegion = region; inputInfo->token = sp<BBinder>::make(); mLifecycleManager.applyTransactions(transactions); @@ -280,9 +279,8 @@ public: transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged; transactions.back().states.front().layerId = id; - transactions.back().states.front().state.windowInfoHandle = - sp<gui::WindowInfoHandle>::make(); - auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo(); + auto inputInfo = transactions.back().states.front().state.editWindowInfo(); + *inputInfo = {}; if (!inputInfo->token) { inputInfo->token = sp<BBinder>::make(); } @@ -299,9 +297,8 @@ public: transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged; transactions.back().states.front().layerId = id; - transactions.back().states.front().state.windowInfoHandle = - sp<gui::WindowInfoHandle>::make(); - auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo(); + auto inputInfo = transactions.back().states.front().state.editWindowInfo(); + *inputInfo = {}; inputInfo->touchableRegion = region; inputInfo->replaceTouchableRegionWithCrop = replaceTouchableRegionWithCrop; transactions.back().states.front().touchCropId = touchCropId; @@ -455,9 +452,8 @@ public: transactions.emplace_back(); transactions.back().states.push_back({}); - transactions.back().states.front().state.what = layer_state_t::eSurfaceDamageRegionChanged; transactions.back().states.front().layerId = id; - transactions.back().states.front().state.surfaceDamageRegion = damageRegion; + transactions.back().states.front().state.updateSurfaceDamageRegion(damageRegion); mLifecycleManager.applyTransactions(transactions); } @@ -485,6 +481,18 @@ public: mLifecycleManager.applyTransactions(transactions); } + void setClientDrawnCornerRadius(uint32_t id, float clientDrawnCornerRadius) { + std::vector<QueuedTransactionState> transactions; + transactions.emplace_back(); + transactions.back().states.push_back({}); + + transactions.back().states.front().state.what = + layer_state_t::eClientDrawnCornerRadiusChanged; + transactions.back().states.front().layerId = id; + transactions.back().states.front().state.clientDrawnCornerRadius = clientDrawnCornerRadius; + mLifecycleManager.applyTransactions(transactions); + } + void setShadowRadius(uint32_t id, float shadowRadius) { std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index 42259af7b0..f1c1549dbc 100644 --- a/services/surfaceflinger/tests/unittests/Android.bp +++ b/services/surfaceflinger/tests/unittests/Android.bp @@ -65,9 +65,9 @@ filegroup { "mock/MockFrameTracer.cpp", "mock/MockNativeWindowSurface.cpp", "mock/MockTimeStats.cpp", - "mock/MockVsyncController.cpp", "mock/MockVSyncDispatch.cpp", "mock/MockVSyncTracker.cpp", + "mock/MockVsyncController.cpp", ], } @@ -87,10 +87,10 @@ cc_test { test_suites: ["device-tests"], header_libs: ["surfaceflinger_tests_common_headers"], srcs: [ + "*.cpp", ":libsurfaceflinger_backend_mock_sources", ":libsurfaceflinger_mock_sources", ":libsurfaceflinger_sources", - "*.cpp", ], } @@ -117,9 +117,8 @@ cc_defaults { "android.hardware.power@1.2", "android.hardware.power@1.3", "libaidlcommonsupport", - "libcompositionengine_mocks", "libcompositionengine", - "libframetimeline", + "libcompositionengine_mocks", "libgmock", "libgui_mocks", "libperfetto_client_experimental", @@ -140,14 +139,15 @@ cc_defaults { "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.common@1.2", + "libEGL", + "libGLESv1_CM", + "libGLESv2", + "libSurfaceFlingerProp", "libbase", "libbinder", "libbinder_ndk", "libcutils", - "libEGL", "libfmq", - "libGLESv1_CM", - "libGLESv2", "libgui", "libhidlbase", "libinput", @@ -157,11 +157,10 @@ cc_defaults { "libprocessgroup", "libprotobuf-cpp-lite", "libstatslog_surfaceflinger", - "libSurfaceFlingerProp", "libsync", + "libtracing_perfetto", "libui", "libutils", - "libtracing_perfetto", ], header_libs: [ "android.hardware.graphics.composer3-command-buffer", diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 71cafbfd64..c342e1eebb 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -36,7 +36,6 @@ #include <system/window.h> #include <utils/String8.h> -#include "DisplayRenderArea.h" #include "Layer.h" #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" @@ -199,25 +198,21 @@ void CompositionTest::captureScreenComposition() { const Rect sourceCrop(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); constexpr bool regionSampling = false; - auto renderArea = - DisplayRenderArea::create(mDisplay, sourceCrop, sourceCrop.getSize(), - ui::Dataspace::V0_SRGB, - RenderArea::Options::CAPTURE_SECURE_LAYERS | - RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION); - auto getLayerSnapshotsFn = mFlinger.getLayerSnapshotsForScreenshotsFn(mDisplay->getLayerStack(), CaptureArgs::UNSET_UID); const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; mCaptureScreenBuffer = - std::make_shared<renderengine::mock::FakeExternalTexture>(renderArea->getReqWidth(), - renderArea->getReqHeight(), + std::make_shared<renderengine::mock::FakeExternalTexture>(sourceCrop.getSize().width, + sourceCrop.getSize().height, HAL_PIXEL_FORMAT_RGBA_8888, 1, usage); - auto future = mFlinger.renderScreenImpl(mDisplay, std::move(renderArea), getLayerSnapshotsFn, - mCaptureScreenBuffer, regionSampling); + auto future = mFlinger.renderScreenImpl(mDisplay, sourceCrop, ui::Dataspace::V0_SRGB, + getLayerSnapshotsFn, mCaptureScreenBuffer, + regionSampling, mDisplay->isSecure(), + /* seamlessTransition */ true); ASSERT_TRUE(future.valid()); const auto fenceResult = future.get(); @@ -473,7 +468,7 @@ struct BaseLayerProperties { layer.externalTexture = buffer; layer.bufferData->acquireFence = Fence::NO_FENCE; layer.dataspace = ui::Dataspace::UNKNOWN; - layer.surfaceDamageRegion = Region(Rect(LayerProperties::HEIGHT, LayerProperties::WIDTH)); + layer.setSurfaceDamageRegion(Region(Rect(LayerProperties::HEIGHT, LayerProperties::WIDTH))); Mock::VerifyAndClear(test->mRenderEngine); } diff --git a/services/surfaceflinger/tests/unittests/DisplayModeControllerTest.cpp b/services/surfaceflinger/tests/unittests/DisplayModeControllerTest.cpp index c6cbe52c4a..84dc5fc4b7 100644 --- a/services/surfaceflinger/tests/unittests/DisplayModeControllerTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayModeControllerTest.cpp @@ -67,7 +67,8 @@ public: setVsyncEnabled(kHwcDisplayId, hal::IComposerClient::Vsync::DISABLE)); EXPECT_CALL(*mComposerHal, onHotplugConnect(kHwcDisplayId)); - const auto infoOpt = mComposer->onHotplug(kHwcDisplayId, hal::Connection::CONNECTED); + const auto infoOpt = + mComposer->onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected); ASSERT_TRUE(infoOpt); mDisplayId = infoOpt->id; diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h index 6e231aa7f4..75182e5fbb 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h @@ -114,7 +114,11 @@ public: // Test instances TestableSurfaceFlinger mFlinger; + sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make(); + sp<compositionengine::mock::DisplaySurface> mDisplaySurface = + sp<compositionengine::mock::DisplaySurface>::make(); + sp<GraphicBuffer> mBuffer = sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN); @@ -179,7 +183,7 @@ struct DisplayIdGetter; template <typename PhysicalDisplay> struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> { - static PhysicalDisplayId get() { + static DisplayIdVariant get() { if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) { return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY) ? LEGACY_DISPLAY_TYPE_PRIMARY @@ -193,14 +197,14 @@ struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> { } }; -template <uint64_t displayId> +template <VirtualDisplayId::BaseId displayId> struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> { - static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); } + static DisplayIdVariant get() { return HalVirtualDisplayId(displayId); } }; template <> struct DisplayIdGetter<GpuVirtualDisplayIdType> { - static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); } + static DisplayIdVariant get() { return GpuVirtualDisplayId(0); } }; template <typename> @@ -294,6 +298,7 @@ struct DisplayVariant { injector.setSecure(static_cast<bool>(SECURE)); injector.setNativeWindow(test->mNativeWindow); + injector.setDisplaySurface(test->mDisplaySurface); // Creating a DisplayDevice requires getting default dimensions from the // native window along with some other initial setup. @@ -360,17 +365,17 @@ struct HwcDisplayVariant { // The HWC active configuration id static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001; - static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) { + static void injectPendingHotplugEvent(DisplayTransactionTest* test, + HWComposer::HotplugEvent event) { test->mFlinger.mutablePendingHotplugEvents().emplace_back( - TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, connection}); + TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, event}); } // Called by tests to inject a HWC display setup template <hal::PowerMode kPowerMode = hal::PowerMode::ON> static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) { - const auto displayId = DisplayVariant::DISPLAY_ID::get(); - ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId)); - TestableSurfaceFlinger::FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE, + TestableSurfaceFlinger::FakeHwcDisplayInjector(DisplayVariant::DISPLAY_ID::get(), + HWC_DISPLAY_TYPE, static_cast<bool>(DisplayVariant::PRIMARY)) .setHwcDisplayId(HWC_DISPLAY_ID) .setResolution(DisplayVariant::RESOLUTION) @@ -532,13 +537,14 @@ struct PrimaryDisplay { static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid; }; -template <ui::DisplayConnectionType connectionType, bool hasIdentificationData, bool secure> +template <ui::DisplayConnectionType connectionType, bool hasIdentificationData, bool secure, + HWDisplayId hwDisplayId = 1002> struct SecondaryDisplay { static constexpr auto CONNECTION_TYPE = connectionType; static constexpr Primary PRIMARY = Primary::FALSE; static constexpr bool SECURE = secure; static constexpr uint8_t PORT = 254; - static constexpr HWDisplayId HWC_DISPLAY_ID = 1002; + static constexpr HWDisplayId HWC_DISPLAY_ID = hwDisplayId; static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData; static constexpr auto GET_IDENTIFICATION_DATA = connectionType == ui::DisplayConnectionType::Internal ? getInternalEdid @@ -570,10 +576,11 @@ using OuterDisplayNonSecureVariant = /*hasIdentificationData=*/true, kNonSecure>, 1080, 2092>; -using ExternalDisplayWithIdentificationVariant = - PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External, - /*hasIdentificationData=*/true, kNonSecure>, - 1920, 1280>; +template <HWDisplayId hwDisplayId = 1002> +using ExternalDisplayWithIdentificationVariant = PhysicalDisplayVariant< + SecondaryDisplay<ui::DisplayConnectionType::External, + /*hasIdentificationData=*/true, kNonSecure, hwDisplayId>, + 1920, 1280>; using ExternalDisplayVariant = PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External, /*hasIdentificationData=*/false, kSecure>, @@ -655,9 +662,8 @@ struct HwcVirtualDisplayVariant const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - const auto displayId = Base::DISPLAY_ID::get(); auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() - .setId(displayId) + .setId(Base::DISPLAY_ID::get()) .setPixels(Base::RESOLUTION) .setIsSecure(static_cast<bool>(Base::SECURE)) .setPowerAdvisor(&test->mPowerAdvisor) @@ -670,7 +676,12 @@ struct HwcVirtualDisplayVariant ceDisplayArgs); // Insert display data so that the HWC thinks it created the virtual display. - test->mFlinger.mutableHwcDisplayData().try_emplace(displayId); + const auto ceDisplayIdVar = compositionDisplay->getDisplayIdVariant(); + LOG_ALWAYS_FATAL_IF(!ceDisplayIdVar); + EXPECT_EQ(*ceDisplayIdVar, Base::DISPLAY_ID::get()); + const auto displayId = asHalDisplayId(*ceDisplayIdVar); + LOG_ALWAYS_FATAL_IF(!displayId); + test->mFlinger.mutableHwcDisplayData().try_emplace(*displayId); return compositionDisplay; } @@ -808,8 +819,9 @@ using HwcVirtualDisplayCase = inline DisplayModePtr createDisplayMode(DisplayModeId modeId, Fps refreshRate, int32_t group = 0, ui::Size resolution = ui::Size(1920, 1080)) { - return mock::createDisplayMode(modeId, refreshRate, group, resolution, - PrimaryDisplayVariant::DISPLAY_ID::get()); + const auto physicalDisplayId = asPhysicalDisplayId(PrimaryDisplayVariant::DISPLAY_ID::get()); + LOG_ALWAYS_FATAL_IF(!physicalDisplayId); + return mock::createDisplayMode(modeId, refreshRate, group, resolution, *physicalDisplayId); } } // namespace android diff --git a/services/surfaceflinger/tests/unittests/DualDisplayTransactionTest.h b/services/surfaceflinger/tests/unittests/DualDisplayTransactionTest.h index 90e716ff1f..edcb639f82 100644 --- a/services/surfaceflinger/tests/unittests/DualDisplayTransactionTest.h +++ b/services/surfaceflinger/tests/unittests/DualDisplayTransactionTest.h @@ -48,8 +48,10 @@ struct DualDisplayTransactionTest : DisplayTransactionTest { } } - static inline PhysicalDisplayId kInnerDisplayId = InnerDisplayVariant::DISPLAY_ID::get(); - static inline PhysicalDisplayId kOuterDisplayId = OuterDisplayVariant::DISPLAY_ID::get(); + static inline PhysicalDisplayId kInnerDisplayId = + asPhysicalDisplayId(InnerDisplayVariant::DISPLAY_ID::get()).value(); + static inline PhysicalDisplayId kOuterDisplayId = + asPhysicalDisplayId(OuterDisplayVariant::DISPLAY_ID::get()).value(); sp<DisplayDevice> mInnerDisplay, mOuterDisplay; }; diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp index 268a6c416d..6f15db8beb 100644 --- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp +++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp @@ -30,7 +30,7 @@ #include "AsyncCallRecorder.h" #include "DisplayHardware/DisplayMode.h" -#include "FrameTimeline.h" +#include "FrameTimeline/FrameTimeline.h" #include "Scheduler/EventThread.h" #include "mock/MockVSyncDispatch.h" #include "mock/MockVSyncTracker.h" @@ -270,7 +270,7 @@ void EventThreadTest::expectVsyncEventReceivedByConnection( ASSERT_TRUE(args.has_value()) << name << " did not receive an event for timestamp " << expectedTimestamp; const auto& event = std::get<0>(args.value()); - EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_VSYNC, event.header.type) + EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_VSYNC, event.header.type) << name << " did not get the correct event for timestamp " << expectedTimestamp; EXPECT_EQ(expectedTimestamp, event.header.timestamp) << name << " did not get the expected timestamp for timestamp " << expectedTimestamp; @@ -344,7 +344,7 @@ void EventThreadTest::expectHotplugEventReceivedByConnection(PhysicalDisplayId e auto args = mConnectionEventCallRecorder.waitForCall(); ASSERT_TRUE(args.has_value()); const auto& event = std::get<0>(args.value()); - EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, event.header.type); + EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_HOTPLUG, event.header.type); EXPECT_EQ(expectedDisplayId, event.header.displayId); EXPECT_EQ(expectedConnected, event.hotplug.connected); } @@ -355,7 +355,7 @@ void EventThreadTest::expectConfigChangedEventReceivedByConnection( auto args = mConnectionEventCallRecorder.waitForCall(); ASSERT_TRUE(args.has_value()); const auto& event = std::get<0>(args.value()); - EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, event.header.type); + EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_MODE_CHANGE, event.header.type); EXPECT_EQ(expectedDisplayId, event.header.displayId); EXPECT_EQ(expectedConfigId, event.modeChange.modeId); EXPECT_EQ(expectedVsyncPeriod, event.modeChange.vsyncPeriod); @@ -367,7 +367,7 @@ void EventThreadTest::expectUidFrameRateMappingEventReceivedByConnection( auto args = mConnectionEventCallRecorder.waitForCall(); ASSERT_TRUE(args.has_value()); const auto& event = std::get<0>(args.value()); - EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE, event.header.type); + EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE, event.header.type); EXPECT_EQ(expectedDisplayId, event.header.displayId); EXPECT_EQ(uid, event.frameRateOverride.uid); EXPECT_EQ(frameRateHz, event.frameRateOverride.frameRateHz); @@ -376,7 +376,7 @@ void EventThreadTest::expectUidFrameRateMappingEventReceivedByConnection( auto args = mConnectionEventCallRecorder.waitForCall(); ASSERT_TRUE(args.has_value()); const auto& event = std::get<0>(args.value()); - EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH, event.header.type); + EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH, event.header.type); EXPECT_EQ(expectedDisplayId, event.header.displayId); } @@ -874,7 +874,7 @@ TEST_F(EventThreadTest, postHcpLevelsChanged) { auto args = mConnectionEventCallRecorder.waitForCall(); ASSERT_TRUE(args.has_value()); const auto& event = std::get<0>(args.value()); - EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE, event.header.type); + EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE, event.header.type); EXPECT_EQ(EXTERNAL_DISPLAY_ID, event.header.displayId); EXPECT_EQ(HDCP_V1, event.hdcpLevelsChange.connectedLevel); EXPECT_EQ(HDCP_V2, event.hdcpLevelsChange.maxLevel); diff --git a/services/surfaceflinger/tests/unittests/FlagManagerTest.cpp b/services/surfaceflinger/tests/unittests/FlagManagerTest.cpp index a5b347a43c..c6da1a1a79 100644 --- a/services/surfaceflinger/tests/unittests/FlagManagerTest.cpp +++ b/services/surfaceflinger/tests/unittests/FlagManagerTest.cpp @@ -125,13 +125,13 @@ TEST_F(FlagManagerTest, DISABLED_returnsOverrideFalse) { TEST_F(FlagManagerTest, ignoresOverrideInUnitTestMode) { mFlagManager.setUnitTestMode(); - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); + SET_FLAG_FOR_TEST(flags::no_vsyncs_on_screen_off, true); // If this has not been called in this process, it will be called. // Regardless, the result is ignored. EXPECT_CALL(mFlagManager, getBoolProperty).WillRepeatedly(Return(false)); - EXPECT_EQ(true, mFlagManager.multithreaded_present()); + EXPECT_EQ(true, mFlagManager.no_vsyncs_on_screen_off()); } TEST_F(FlagManagerTest, returnsValue) { diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp index 08e426564a..54f225901e 100644 --- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp @@ -202,10 +202,12 @@ public: uint32_t* maxDisplayFrames; size_t maxTokens; static constexpr pid_t kSurfaceFlingerPid = 666; - static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count(); + static constexpr nsecs_t kPresentThresholdLegacy = std::chrono::nanoseconds(2ns).count(); + static constexpr nsecs_t kPresentThresholdExtended = std::chrono::nanoseconds(4ns).count(); static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count(); static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count(); - static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold, + static constexpr JankClassificationThresholds kTestThresholds{kPresentThresholdLegacy, + kPresentThresholdExtended, kDeadlineThreshold, kStartThreshold}; }; diff --git a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp index ba2d3e28ad..b34de1a516 100644 --- a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp +++ b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp @@ -94,7 +94,7 @@ TEST_F(HWComposerTest, isHeadless) { constexpr hal::HWDisplayId kHwcDisplayId = 1; expectHotplugConnect(kHwcDisplayId); - const auto info = mHwc.onHotplug(kHwcDisplayId, hal::Connection::CONNECTED); + const auto info = mHwc.onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected); ASSERT_TRUE(info); ASSERT_FALSE(mHwc.isHeadless()); @@ -111,7 +111,7 @@ TEST_F(HWComposerTest, getDisplayConnectionType) { constexpr hal::HWDisplayId kHwcDisplayId = 1; expectHotplugConnect(kHwcDisplayId); - const auto info = mHwc.onHotplug(kHwcDisplayId, hal::Connection::CONNECTED); + const auto info = mHwc.onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected); ASSERT_TRUE(info); EXPECT_CALL(*mHal, getDisplayConnectionType(kHwcDisplayId, _)) @@ -133,7 +133,7 @@ TEST_F(HWComposerTest, getActiveMode) { constexpr hal::HWDisplayId kHwcDisplayId = 2; expectHotplugConnect(kHwcDisplayId); - const auto info = mHwc.onHotplug(kHwcDisplayId, hal::Connection::CONNECTED); + const auto info = mHwc.onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected); ASSERT_TRUE(info); { @@ -164,7 +164,7 @@ TEST_F(HWComposerTest, getModesWithLegacyDisplayConfigs) { constexpr int32_t kMaxFrameIntervalNs = 50000000; // 20Fps expectHotplugConnect(kHwcDisplayId); - const auto info = mHwc.onHotplug(kHwcDisplayId, hal::Connection::CONNECTED); + const auto info = mHwc.onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected); ASSERT_TRUE(info); ASSERT_TRUE(info->preferredDetailedTimingDescriptor.has_value()); @@ -266,7 +266,7 @@ TEST_F(HWComposerTest, getModesWithDisplayConfigurations_VRR_OFF) { constexpr int32_t kMaxFrameIntervalNs = 50000000; // 20Fps expectHotplugConnect(kHwcDisplayId); - const auto info = mHwc.onHotplug(kHwcDisplayId, hal::Connection::CONNECTED); + const auto info = mHwc.onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected); ASSERT_TRUE(info); EXPECT_CALL(*mHal, isVrrSupported()).WillRepeatedly(Return(false)); @@ -364,7 +364,7 @@ TEST_F(HWComposerTest, getModesWithDisplayConfigurations_VRR_ON) { constexpr hal::HWConfigId kConfigId = 42; constexpr int32_t kMaxFrameIntervalNs = 50000000; // 20Fps expectHotplugConnect(kHwcDisplayId); - const auto info = mHwc.onHotplug(kHwcDisplayId, hal::Connection::CONNECTED); + const auto info = mHwc.onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected); ASSERT_TRUE(info); EXPECT_CALL(*mHal, isVrrSupported()).WillRepeatedly(Return(true)); @@ -452,7 +452,7 @@ TEST_F(HWComposerTest, onVsync) { constexpr hal::HWDisplayId kHwcDisplayId = 1; expectHotplugConnect(kHwcDisplayId); - const auto info = mHwc.onHotplug(kHwcDisplayId, hal::Connection::CONNECTED); + const auto info = mHwc.onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected); ASSERT_TRUE(info); const auto physicalDisplayId = info->id; diff --git a/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp b/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp index 2941a14ef9..0f16073b07 100644 --- a/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp +++ b/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp @@ -213,4 +213,33 @@ TEST_F(JankTrackerTest, listenerCountIsAccurateOnDuplicateRegistration) { EXPECT_EQ(listenerCount(), 0u); } -} // namespace android
\ No newline at end of file +TEST_F(JankTrackerTest, multipleLayersAreTrackedIndependently) { + size_t jankDataReceived = 0; + size_t numBatchesReceived = 0; + + EXPECT_CALL(*mListener.get(), onJankData(_)) + .WillRepeatedly([&](const std::vector<gui::JankData>& jankData) { + jankDataReceived += jankData.size(); + numBatchesReceived++; + return binder::Status::ok(); + }); + addJankListener(123); + addJankListener(321); + addJankData(123, 1); + addJankData(123, 2); + addJankData(123, 3); + addJankData(321, 4); + addJankData(321, 5); + + JankTracker::flushJankData(123); + flushBackgroundThread(); + EXPECT_EQ(numBatchesReceived, 1u); + EXPECT_EQ(jankDataReceived, 3u); + + JankTracker::flushJankData(321); + flushBackgroundThread(); + EXPECT_EQ(numBatchesReceived, 2u); + EXPECT_EQ(jankDataReceived, 5u); +} + +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp index 976cecbe40..35ec536d14 100644 --- a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp @@ -619,14 +619,32 @@ TEST_F(LayerLifecycleManagerTest, isSimpleBufferUpdate) { } } -TEST_F(LayerLifecycleManagerTest, testInputInfoOfRequestedLayerState) { - // By default the layer has no buffer, so it doesn't need an input info - EXPECT_FALSE(getRequestedLayerState(mLifecycleManager, 111)->needsInputInfo()); +TEST_F(LayerLifecycleManagerTest, layerWithBufferNeedsInputInfo) { + // If a layer has no buffer or no color, it doesn't have an input info + LayerHierarchyTestBase::createRootLayer(3); + setColor(3, {-1._hf, -1._hf, -1._hf}); + mLifecycleManager.commitChanges(); + + EXPECT_FALSE(getRequestedLayerState(mLifecycleManager, 3)->needsInputInfo()); + + setBuffer(3); + mLifecycleManager.commitChanges(); + + EXPECT_TRUE(getRequestedLayerState(mLifecycleManager, 3)->needsInputInfo()); +} + +TEST_F(LayerLifecycleManagerTest, layerWithColorNeedsInputInfo) { + // If a layer has no buffer or no color, it doesn't have an input info + LayerHierarchyTestBase::createRootLayer(4); + setColor(4, {-1._hf, -1._hf, -1._hf}); + mLifecycleManager.commitChanges(); + + EXPECT_FALSE(getRequestedLayerState(mLifecycleManager, 4)->needsInputInfo()); - setBuffer(111); + setColor(4, {1._hf, 0._hf, 0._hf}); mLifecycleManager.commitChanges(); - EXPECT_TRUE(getRequestedLayerState(mLifecycleManager, 111)->needsInputInfo()); + EXPECT_TRUE(getRequestedLayerState(mLifecycleManager, 4)->needsInputInfo()); } } // namespace android::surfaceflinger::frontend diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp index 1177d1601e..07356b9ec9 100644 --- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp @@ -28,6 +28,7 @@ #include "ui/GraphicTypes.h" #include <com_android_graphics_libgui_flags.h> +#include <cmath> #define UPDATE_AND_VERIFY(BUILDER, ...) \ ({ \ @@ -260,6 +261,40 @@ TEST_F(LayerSnapshotTest, AlphaInheritedByChildren) { EXPECT_EQ(getSnapshot(1221)->alpha, 0.25f); } +TEST_F(LayerSnapshotTest, AlphaInheritedByChildWhenParentIsHiddenByInvalidTransform) { + setMatrix(1, 0, 0, 0, 0); + update(mSnapshotBuilder); + mLifecycleManager.commitChanges(); + + setAlpha(1, 0.5); + update(mSnapshotBuilder); + mLifecycleManager.commitChanges(); + + setMatrix(1, 1, 0, 0, 1); + update(mSnapshotBuilder); + mLifecycleManager.commitChanges(); + + EXPECT_EQ(getSnapshot(1)->alpha, 0.5f); + EXPECT_EQ(getSnapshot(11)->alpha, 0.5f); +} + +TEST_F(LayerSnapshotTest, AlphaInheritedByChildWhenParentIsHidden) { + hideLayer(1); + update(mSnapshotBuilder); + mLifecycleManager.commitChanges(); + + setAlpha(1, 0.5); + update(mSnapshotBuilder); + mLifecycleManager.commitChanges(); + + showLayer(1); + update(mSnapshotBuilder); + mLifecycleManager.commitChanges(); + + EXPECT_EQ(getSnapshot(1)->alpha, 0.5f); + EXPECT_EQ(getSnapshot(11)->alpha, 0.5f); +} + // Change states TEST_F(LayerSnapshotTest, UpdateClearsPreviousChangeStates) { setCrop(1, Rect(1, 2, 3, 4)); @@ -1425,6 +1460,85 @@ TEST_F(LayerSnapshotTest, setBufferCrop) { EXPECT_EQ(getSnapshot(1)->geomContentCrop, Rect(0, 0, 100, 100)); } +TEST_F(LayerSnapshotTest, setCornerRadius) { + static constexpr float RADIUS = 123.f; + setRoundedCorners(1, RADIUS); + setCrop(1, Rect{1000, 1000}); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_EQ(getSnapshot({.id = 1})->roundedCorner.radius.x, RADIUS); +} + +TEST_F(LayerSnapshotTest, ignoreCornerRadius) { + static constexpr float RADIUS = 123.f; + setClientDrawnCornerRadius(1, RADIUS); + setRoundedCorners(1, RADIUS); + setCrop(1, Rect{1000, 1000}); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_TRUE(getSnapshot({.id = 1})->roundedCorner.hasClientDrawnRadius()); + EXPECT_EQ(getSnapshot({.id = 1})->roundedCorner.radius.x, 0.f); +} + +TEST_F(LayerSnapshotTest, childInheritsParentScaledSettings) { + // ROOT + // ├── 1 (crop rect set to contain child layer) + // │ ├── 11 + static constexpr float RADIUS = 123.f; + + setRoundedCorners(1, RADIUS); + FloatRect parentCropRect(1, 1, 999, 999); + setCrop(1, parentCropRect); + // Rotate surface by 90 + setMatrix(11, 0.f, -1.f, 1.f, 0.f); + + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + + ui::Transform t = getSnapshot({.id = 11})->localTransform.inverse(); + + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_EQ(getSnapshot({.id = 11})->roundedCorner.cropRect, t.transform(parentCropRect)); + EXPECT_EQ(getSnapshot({.id = 11})->roundedCorner.radius.x, RADIUS * t.getScaleX()); + EXPECT_EQ(getSnapshot({.id = 11})->roundedCorner.radius.y, RADIUS * t.getScaleY()); + EXPECT_EQ(getSnapshot({.id = 11})->roundedCorner.requestedRadius.x, RADIUS * t.getScaleX()); + EXPECT_EQ(getSnapshot({.id = 11})->roundedCorner.requestedRadius.y, RADIUS * t.getScaleY()); +} + +TEST_F(LayerSnapshotTest, childInheritsParentClientDrawnCornerRadius) { + // ROOT + // ├── 1 (crop rect set to contain child layers ) + // │ ├── 11 + // │ │ └── 111 + + static constexpr float RADIUS = 123.f; + + setClientDrawnCornerRadius(1, RADIUS); + setRoundedCorners(1, RADIUS); + setCrop(1, Rect(1, 1, 999, 999)); + + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_TRUE(getSnapshot({.id = 1})->roundedCorner.hasClientDrawnRadius()); + EXPECT_TRUE(getSnapshot({.id = 11})->roundedCorner.hasRoundedCorners()); + EXPECT_EQ(getSnapshot({.id = 11})->roundedCorner.radius.x, RADIUS); +} + +TEST_F(LayerSnapshotTest, childIgnoreCornerRadiusOverridesParent) { + // ROOT + // ├── 1 (crop rect set to contain child layers ) + // │ ├── 11 + // │ │ └── 111 + + static constexpr float RADIUS = 123.f; + + setRoundedCorners(1, RADIUS); + setCrop(1, Rect(1, 1, 999, 999)); + + setClientDrawnCornerRadius(11, RADIUS); + + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_EQ(getSnapshot({.id = 1})->roundedCorner.radius.x, RADIUS); + EXPECT_EQ(getSnapshot({.id = 11})->roundedCorner.radius.x, 0.f); + EXPECT_EQ(getSnapshot({.id = 111})->roundedCorner.radius.x, RADIUS); +} + TEST_F(LayerSnapshotTest, setShadowRadius) { static constexpr float SHADOW_RADIUS = 123.f; setShadowRadius(1, SHADOW_RADIUS); @@ -1562,8 +1676,8 @@ TEST_F(LayerSnapshotTest, NonVisibleLayerWithInput) { transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged; transactions.back().states.front().layerId = 3; - transactions.back().states.front().state.windowInfoHandle = sp<gui::WindowInfoHandle>::make(); - auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo(); + auto inputInfo = transactions.back().states.front().state.editWindowInfo(); + *inputInfo = {}; inputInfo->token = sp<BBinder>::make(); mLifecycleManager.applyTransactions(transactions); @@ -1591,8 +1705,8 @@ TEST_F(LayerSnapshotTest, NonVisibleLayerWithInputShouldNotBeIncluded) { transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged; transactions.back().states.front().layerId = 3; - transactions.back().states.front().state.windowInfoHandle = sp<gui::WindowInfoHandle>::make(); - auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo(); + auto inputInfo = transactions.back().states.front().state.editWindowInfo(); + *inputInfo = {}; inputInfo->token = sp<BBinder>::make(); hideLayer(3); mLifecycleManager.applyTransactions(transactions); @@ -1799,9 +1913,6 @@ TEST_F(LayerSnapshotTest, hideLayerWithNanMatrix) { } TEST_F(LayerSnapshotTest, edgeExtensionPropagatesInHierarchy) { - if (!com::android::graphics::libgui::flags::edge_extension_shader()) { - GTEST_SKIP() << "Skipping test because edge_extension_shader is off"; - } setCrop(1, Rect(0, 0, 20, 20)); setBuffer(1221, std::make_shared<renderengine::mock::FakeExternalTexture>(20 /* width */, @@ -1840,9 +1951,6 @@ TEST_F(LayerSnapshotTest, edgeExtensionPropagatesInHierarchy) { TEST_F(LayerSnapshotTest, leftEdgeExtensionIncreaseBoundSizeWithinCrop) { // The left bound is extended when shifting to the right - if (!com::android::graphics::libgui::flags::edge_extension_shader()) { - GTEST_SKIP() << "Skipping test because edge_extension_shader is off"; - } setCrop(1, Rect(0, 0, 20, 20)); const int texSize = 10; setBuffer(1221, @@ -1862,9 +1970,6 @@ TEST_F(LayerSnapshotTest, leftEdgeExtensionIncreaseBoundSizeWithinCrop) { TEST_F(LayerSnapshotTest, rightEdgeExtensionIncreaseBoundSizeWithinCrop) { // The right bound is extended when shifting to the left - if (!com::android::graphics::libgui::flags::edge_extension_shader()) { - GTEST_SKIP() << "Skipping test because edge_extension_shader is off"; - } const int crop = 20; setCrop(1, Rect(0, 0, crop, crop)); const int texSize = 10; @@ -1885,9 +1990,6 @@ TEST_F(LayerSnapshotTest, rightEdgeExtensionIncreaseBoundSizeWithinCrop) { TEST_F(LayerSnapshotTest, topEdgeExtensionIncreaseBoundSizeWithinCrop) { // The top bound is extended when shifting to the bottom - if (!com::android::graphics::libgui::flags::edge_extension_shader()) { - GTEST_SKIP() << "Skipping test because edge_extension_shader is off"; - } setCrop(1, Rect(0, 0, 20, 20)); const int texSize = 10; setBuffer(1221, @@ -1907,9 +2009,6 @@ TEST_F(LayerSnapshotTest, topEdgeExtensionIncreaseBoundSizeWithinCrop) { TEST_F(LayerSnapshotTest, bottomEdgeExtensionIncreaseBoundSizeWithinCrop) { // The bottom bound is extended when shifting to the top - if (!com::android::graphics::libgui::flags::edge_extension_shader()) { - GTEST_SKIP() << "Skipping test because edge_extension_shader is off"; - } const int crop = 20; setCrop(1, Rect(0, 0, crop, crop)); const int texSize = 10; @@ -1930,9 +2029,6 @@ TEST_F(LayerSnapshotTest, bottomEdgeExtensionIncreaseBoundSizeWithinCrop) { TEST_F(LayerSnapshotTest, multipleEdgeExtensionIncreaseBoundSizeWithinCrop) { // The left bound is extended when shifting to the right - if (!com::android::graphics::libgui::flags::edge_extension_shader()) { - GTEST_SKIP() << "Skipping test because edge_extension_shader is off"; - } const int crop = 20; setCrop(1, Rect(0, 0, crop, crop)); const int texSize = 10; @@ -1957,17 +2053,17 @@ TEST_F(LayerSnapshotTest, multipleEdgeExtensionIncreaseBoundSizeWithinCrop) { } TEST_F(LayerSnapshotTest, shouldUpdateInputWhenNoInputInfo) { - // By default the layer has no buffer, so we don't expect it to have an input info + // If a layer has no buffer or no color, it doesn't have an input info + setColor(111, {-1._hf, -1._hf, -1._hf}); + UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 11, 12, 121, 122, 1221, 13, 2}); EXPECT_FALSE(getSnapshot(111)->hasInputInfo()); setBuffer(111); - UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); EXPECT_TRUE(getSnapshot(111)->hasInputInfo()); EXPECT_TRUE(getSnapshot(111)->inputInfo.inputConfig.test( gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL)); - EXPECT_FALSE(getSnapshot(2)->hasInputInfo()); } // content dirty test diff --git a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp index 908637ae76..e9b86b270a 100644 --- a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp +++ b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp @@ -22,7 +22,7 @@ #include <scheduler/interface/ICompositor.h> -#include "FrameTimeline.h" +#include "FrameTimeline/FrameTimeline.h" #include "Scheduler/MessageQueue.h" #include "mock/MockVSyncDispatch.h" #include "utils/Timers.h" diff --git a/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp b/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp index 5c25f34ae7..d7f7bdb9db 100644 --- a/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp +++ b/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp @@ -39,6 +39,7 @@ using namespace android::hardware::power; using namespace std::chrono_literals; using namespace testing; using namespace android::power; +using namespace ftl::flag_operators; namespace android::adpf::impl { @@ -54,6 +55,8 @@ public: void setTimingTestingMode(bool testinMode); void allowReportActualToAcquireMutex(); bool sessionExists(); + ftl::Flags<Workload> getCommittedWorkload() const; + ftl::Flags<Workload> getQueuedWorkload() const; int64_t toNanos(Duration d); struct GpuTestConfig { @@ -315,6 +318,14 @@ Duration PowerAdvisorTest::getErrorMargin() { return mPowerAdvisor->sTargetSafetyMargin; } +ftl::Flags<Workload> PowerAdvisorTest::getCommittedWorkload() const { + return mPowerAdvisor->mCommittedWorkload; +} + +ftl::Flags<Workload> PowerAdvisorTest::getQueuedWorkload() const { + return ftl::Flags<Workload>{mPowerAdvisor->mQueuedWorkload.load()}; +} + namespace { TEST_F(PowerAdvisorTest, hintSessionUseHwcDisplay) { @@ -842,5 +853,32 @@ TEST_F(PowerAdvisorTest, fmq_sendHint_queueFull) { ASSERT_EQ(hint, SessionHint::CPU_LOAD_UP); } +TEST_F(PowerAdvisorTest, trackQueuedWorkloads) { + mPowerAdvisor->setQueuedWorkload(ftl::Flags<Workload>()); + ASSERT_EQ(getQueuedWorkload(), ftl::Flags<Workload>()); + + // verify workloads are queued + mPowerAdvisor->setQueuedWorkload(ftl::Flags<Workload>(Workload::VISIBLE_REGION)); + ASSERT_EQ(getQueuedWorkload(), ftl::Flags<Workload>(Workload::VISIBLE_REGION)); + + mPowerAdvisor->setQueuedWorkload(ftl::Flags<Workload>(Workload::EFFECTS)); + ASSERT_EQ(getQueuedWorkload(), Workload::VISIBLE_REGION | Workload::EFFECTS); + + // verify queued workloads are cleared after commit + mPowerAdvisor->setCommittedWorkload(ftl::Flags<Workload>()); + ASSERT_EQ(getQueuedWorkload(), ftl::Flags<Workload>()); +} + +TEST_F(PowerAdvisorTest, trackCommittedWorkloads) { + // verify queued workloads are cleared after commit + mPowerAdvisor->setCommittedWorkload(Workload::SCREENSHOT | Workload::VISIBLE_REGION); + ASSERT_EQ(getCommittedWorkload(), Workload::SCREENSHOT | Workload::VISIBLE_REGION); + + // on composite, verify we update the committed workload so we track workload increases for the + // next frame accurately + mPowerAdvisor->setCompositedWorkload(Workload::VISIBLE_REGION | Workload::DISPLAY_CHANGES); + ASSERT_EQ(getCommittedWorkload(), Workload::VISIBLE_REGION | Workload::DISPLAY_CHANGES); +} + } // namespace } // namespace android::adpf::impl diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp index 1fc874dad8..116fcd9f6d 100644 --- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp +++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp @@ -143,7 +143,7 @@ TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) { kDisplay1Mode60->getId())); // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by - // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal. + // Scheduler::setDisplayPowerMode rather than SF::setPhysicalDisplayPowerMode. #if 0 // Hardware VSYNC should be disabled for newly registered displays. EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1); @@ -254,18 +254,43 @@ TEST_F(SchedulerTest, emitModeChangeEvent) { } TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) { - EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms)); - EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms)); - EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms)); + struct TestCase { + Fps refreshRate; + std::chrono::nanoseconds presentLatency; + int expectedBufferCount; + }; - EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms)); + const auto verifyTestCases = [&](std::vector<TestCase> tests) { + for (const auto testCase : tests) { + EXPECT_EQ(testCase.expectedBufferCount, + mFlinger.calculateMaxAcquiredBufferCount(testCase.refreshRate, + testCase.presentLatency)); + } + }; - EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms)); + std::vector<TestCase> testCases{{60_Hz, 30ms, 1}, + {90_Hz, 30ms, 2}, + {120_Hz, 30ms, 3}, + {60_Hz, 40ms, 2}, + {60_Hz, 10ms, 1}}; + verifyTestCases(testCases); const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers(); mFlinger.mutableMinAcquiredBuffers() = 2; - EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms)); + verifyTestCases({{60_Hz, 10ms, 2}}); mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers; + + const auto savedMaxAcquiredBuffers = mFlinger.mutableMaxAcquiredBuffers(); + mFlinger.mutableMaxAcquiredBuffers() = 2; + testCases = {{60_Hz, 30ms, 1}, + {90_Hz, 30ms, 2}, + {120_Hz, 30ms, 2}, // max buffers allowed is 2 + {60_Hz, 40ms, 2}, + {60_Hz, 10ms, 1}}; + verifyTestCases(testCases); + mFlinger.mutableMaxAcquiredBuffers() = 3; // max buffers allowed is 3 + verifyTestCases({{120_Hz, 30ms, 3}}); + mFlinger.mutableMaxAcquiredBuffers() = savedMaxAcquiredBuffers; } MATCHER(Is120Hz, "") { @@ -716,8 +741,6 @@ TEST_F(SchedulerTest, resyncAllDoNotAllow) FTL_FAKE_GUARD(kMainThreadContext) { } TEST_F(SchedulerTest, resyncAllSkipsOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) { - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); - // resyncAllToHardwareVsync will result in requesting hardware VSYNC on display 1, which is on, // but not on display 2, which is off. EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1); @@ -738,28 +761,6 @@ TEST_F(SchedulerTest, resyncAllSkipsOffDisplays) FTL_FAKE_GUARD(kMainThreadConte mScheduler->resyncAllToHardwareVsync(kAllowToEnable); } -TEST_F(SchedulerTest, resyncAllLegacyAppliesToOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) { - SET_FLAG_FOR_TEST(flags::multithreaded_present, false); - - // In the legacy code, prior to the flag, resync applied to OFF displays. - EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1); - EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1); - - mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON); - - mScheduler->registerDisplay(kDisplayId2, - std::make_shared<RefreshRateSelector>(kDisplay2Modes, - kDisplay2Mode60->getId())); - ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2)); - - static constexpr bool kDisallow = true; - mScheduler->disableHardwareVsync(kDisplayId1, kDisallow); - mScheduler->disableHardwareVsync(kDisplayId2, kDisallow); - - static constexpr bool kAllowToEnable = true; - mScheduler->resyncAllToHardwareVsync(kAllowToEnable); -} - class AttachedChoreographerTest : public SchedulerTest { protected: void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps, diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp index 2d3ebb47bd..aa48c1b26a 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp @@ -27,7 +27,8 @@ namespace { class CreateDisplayTest : public DisplayTransactionTest { public: - void createDisplayWithRequestedRefreshRate(const std::string& name, uint64_t displayId, + void createDisplayWithRequestedRefreshRate(const std::string& name, + VirtualDisplayId::BaseId baseId, float pacesetterDisplayRefreshRate, float requestedRefreshRate, float expectedAdjustedRefreshRate) { @@ -49,12 +50,10 @@ public: EXPECT_EQ(display.requestedRefreshRate, Fps::fromValue(requestedRefreshRate)); EXPECT_EQ(name.c_str(), display.displayName); - std::optional<VirtualDisplayId> vid = - DisplayId::fromValue<VirtualDisplayId>(displayId | DisplayId::FLAG_VIRTUAL); - ASSERT_TRUE(vid.has_value()); - sp<DisplayDevice> device = - mFlinger.createVirtualDisplayDevice(displayToken, *vid, requestedRefreshRate); + mFlinger.createVirtualDisplayDevice(displayToken, GpuVirtualDisplayId(baseId), + requestedRefreshRate); + EXPECT_TRUE(device->isVirtual()); device->adjustRefreshRate(Fps::fromValue(pacesetterDisplayRefreshRate)); // verifying desired value @@ -142,7 +141,11 @@ TEST_F(CreateDisplayTest, createDisplaySetsCurrentStateForUniqueId) { // -------------------------------------------------------------------- // Invocation - sp<IBinder> displayToken = mFlinger.createVirtualDisplay(kDisplayName, false, kUniqueId); + sp<IBinder> displayToken = + mFlinger.createVirtualDisplay(kDisplayName, false, + gui::ISurfaceComposer::OptimizationPolicy:: + optimizeForPower, + kUniqueId); // -------------------------------------------------------------------- // Postconditions diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp index a506873d4c..3f710fdf6b 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp @@ -171,16 +171,22 @@ protected: static constexpr DisplayModeId kModeId90{1}; static constexpr DisplayModeId kModeId120{2}; static constexpr DisplayModeId kModeId90_4K{3}; + static constexpr DisplayModeId kModeId60_8K{4}; static inline const DisplayModePtr kMode60 = createDisplayMode(kModeId60, 60_Hz, 0); static inline const DisplayModePtr kMode90 = createDisplayMode(kModeId90, 90_Hz, 1); static inline const DisplayModePtr kMode120 = createDisplayMode(kModeId120, 120_Hz, 2); static constexpr ui::Size kResolution4K{3840, 2160}; + static constexpr ui::Size kResolution8K{7680, 4320}; + static inline const DisplayModePtr kMode90_4K = createDisplayMode(kModeId90_4K, 90_Hz, 3, kResolution4K); + static inline const DisplayModePtr kMode60_8K = + createDisplayMode(kModeId60_8K, 60_Hz, 4, kResolution8K); - static inline const DisplayModes kModes = makeModes(kMode60, kMode90, kMode120, kMode90_4K); + static inline const DisplayModes kModes = + makeModes(kMode60, kMode90, kMode120, kMode90_4K, kMode60_8K); }; void DisplayModeSwitchingTest::setupScheduler( @@ -326,6 +332,8 @@ TEST_F(DisplayModeSwitchingTest, twoConsecutiveSetDesiredDisplayModeSpecs) { } TEST_F(DisplayModeSwitchingTest, changeResolutionWithoutRefreshRequired) { + SET_FLAG_FOR_TEST(flags::synced_resolution_switch, false); + EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60)); EXPECT_EQ(NO_ERROR, @@ -360,9 +368,45 @@ TEST_F(DisplayModeSwitchingTest, changeResolutionWithoutRefreshRequired) { EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId90_4K)); } -TEST_F(DisplayModeSwitchingTest, innerXorOuterDisplay) { - SET_FLAG_FOR_TEST(flags::connected_display, true); +TEST_F(DisplayModeSwitchingTest, changeResolutionSynced) { + SET_FLAG_FOR_TEST(flags::synced_resolution_switch, true); + EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60)); + + // PrimaryDisplayVariant has a 4K size, so switch to 8K. + EXPECT_EQ(NO_ERROR, + mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(), + mock::createDisplayModeSpecs(kModeId60_8K, + 60_Hz))); + + EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId60_8K)); + + // The mode should not be set until the commit that resizes the display. + mFlinger.commit(); + EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId60_8K)); + mFlinger.commit(); + EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId60_8K)); + + // Set the display size to match the resolution. + DisplayState state; + state.what = DisplayState::eDisplaySizeChanged; + state.token = mDisplay->getDisplayToken().promote(); + state.width = static_cast<uint32_t>(kResolution8K.width); + state.height = static_cast<uint32_t>(kResolution8K.height); + + // The next commit should set the mode and resize the framebuffer. + const VsyncPeriodChangeTimeline timeline{.refreshRequired = false}; + EXPECT_CALL(*mDisplaySurface, resizeBuffers(kResolution8K)); + EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId60_8K); + + constexpr bool kModeset = true; + mFlinger.setDisplayStateLocked(state); + mFlinger.configureAndCommit(kModeset); + + EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60_8K)); +} + +TEST_F(DisplayModeSwitchingTest, innerXorOuterDisplay) { const auto [innerDisplay, outerDisplay] = injectOuterDisplay(); EXPECT_TRUE(innerDisplay->isPoweredOn()); @@ -371,8 +415,8 @@ TEST_F(DisplayModeSwitchingTest, innerXorOuterDisplay) { EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId60)); EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId120)); - mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::OFF); - mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(outerDisplay, hal::PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(innerDisplay, hal::PowerMode::ON); EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId60)); EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId120)); @@ -402,8 +446,8 @@ TEST_F(DisplayModeSwitchingTest, innerXorOuterDisplay) { EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId90)); EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId60)); - mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::OFF); - mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(innerDisplay, hal::PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(outerDisplay, hal::PowerMode::ON); EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId90)); EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId60)); @@ -427,8 +471,6 @@ TEST_F(DisplayModeSwitchingTest, innerXorOuterDisplay) { } TEST_F(DisplayModeSwitchingTest, innerAndOuterDisplay) { - SET_FLAG_FOR_TEST(flags::connected_display, true); - const auto [innerDisplay, outerDisplay] = injectOuterDisplay(); EXPECT_TRUE(innerDisplay->isPoweredOn()); @@ -437,8 +479,8 @@ TEST_F(DisplayModeSwitchingTest, innerAndOuterDisplay) { EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId60)); EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId120)); - mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::ON); - mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(innerDisplay, hal::PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(outerDisplay, hal::PowerMode::ON); EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId60)); EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId120)); @@ -480,7 +522,7 @@ TEST_F(DisplayModeSwitchingTest, powerOffDuringModeSet) { EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId90)); // Power off the display before the mode has been set. - mFlinger.setPowerModeInternal(mDisplay, hal::PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(mDisplay, hal::PowerMode::OFF); const VsyncPeriodChangeTimeline timeline{.refreshRequired = true}; EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90); @@ -497,8 +539,6 @@ TEST_F(DisplayModeSwitchingTest, powerOffDuringModeSet) { } TEST_F(DisplayModeSwitchingTest, powerOffDuringConcurrentModeSet) { - SET_FLAG_FOR_TEST(flags::connected_display, true); - const auto [innerDisplay, outerDisplay] = injectOuterDisplay(); EXPECT_TRUE(innerDisplay->isPoweredOn()); @@ -507,8 +547,8 @@ TEST_F(DisplayModeSwitchingTest, powerOffDuringConcurrentModeSet) { EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId60)); EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId120)); - mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::ON); - mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(innerDisplay, hal::PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(outerDisplay, hal::PowerMode::ON); EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId60)); EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId120)); @@ -525,7 +565,7 @@ TEST_F(DisplayModeSwitchingTest, powerOffDuringConcurrentModeSet) { EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60)); // Power off the outer display before the mode has been set. - mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(outerDisplay, hal::PowerMode::OFF); const VsyncPeriodChangeTimeline timeline{.refreshRequired = true}; EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90); @@ -542,8 +582,8 @@ TEST_F(DisplayModeSwitchingTest, powerOffDuringConcurrentModeSet) { EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId90)); EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId60)); - mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::OFF); - mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(innerDisplay, hal::PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(outerDisplay, hal::PowerMode::ON); EXPECT_EQ(NO_ERROR, mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(), diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp index 9bf344c7af..eac5a8e9c5 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp @@ -68,13 +68,9 @@ void DisplayTransactionCommitTest::setupCommonPreconditions() { template <typename Case, bool connected> void DisplayTransactionCommitTest::expectHotplugReceived(mock::EventThread* eventThread) { - const auto convert = [](auto physicalDisplayId) { - return std::make_optional(DisplayId{physicalDisplayId}); - }; - - EXPECT_CALL(*eventThread, - onHotplugReceived(ResultOf(convert, Case::Display::DISPLAY_ID::get()), connected)) - .Times(1); + const auto physicalDisplayId = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get()); + ASSERT_TRUE(physicalDisplayId); + EXPECT_CALL(*eventThread, onHotplugReceived(*physicalDisplayId, connected)).Times(1); } template <typename Case> @@ -111,7 +107,7 @@ void DisplayTransactionCommitTest::verifyDisplayIsConnected(const sp<IBinder>& d std::optional<DisplayDeviceState::Physical> expectedPhysical; if (Case::Display::CONNECTION_TYPE::value) { - const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get()); + const auto displayId = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get()); ASSERT_TRUE(displayId); const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value; ASSERT_TRUE(hwcDisplayId); @@ -137,10 +133,10 @@ void DisplayTransactionCommitTest::verifyPhysicalDisplayIsConnected() { EXPECT_TRUE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID)); // SF should have a display token. - const auto displayId = Case::Display::DISPLAY_ID::get(); - ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId)); + const auto displayIdOpt = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get()); + ASSERT_TRUE(displayIdOpt); - const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(displayId); + const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(*displayIdOpt); ASSERT_TRUE(displayOpt); const auto& display = displayOpt->get(); @@ -163,7 +159,7 @@ void DisplayTransactionCommitTest::processesHotplugConnectCommon() { setupCommonPreconditions<Case>(); // A hotplug connect event is enqueued for a display - Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED); + Case::Display::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); // -------------------------------------------------------------------- // Call Expectations @@ -197,7 +193,7 @@ void DisplayTransactionCommitTest::ignoresHotplugConnectCommon() { setupCommonPreconditions<Case>(); // A hotplug connect event is enqueued for a display - Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED); + Case::Display::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); // -------------------------------------------------------------------- // Invocation @@ -219,7 +215,7 @@ void DisplayTransactionCommitTest::processesHotplugDisconnectCommon() { setupCommonPreconditions<Case>(); // A hotplug disconnect event is enqueued for a display - Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED); + Case::Display::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Disconnected); // The display is already completely set up. Case::Display::injectHwcDisplay(this); @@ -246,9 +242,9 @@ void DisplayTransactionCommitTest::processesHotplugDisconnectCommon() { EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID)); // SF should not have a PhysicalDisplay. - const auto displayId = Case::Display::DISPLAY_ID::get(); - ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId)); - ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(displayId)); + const auto physicalDisplayIdOpt = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get()); + ASSERT_TRUE(physicalDisplayIdOpt); + ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(*physicalDisplayIdOpt)); // The existing token should have been removed. verifyDisplayIsNotConnected(existing.token()); @@ -327,9 +323,10 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugConnectThenDisconnectPrimar setupCommonPreconditions<Case>(); // A hotplug connect event is enqueued for a display - Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED); + Case::Display::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); // A hotplug disconnect event is also enqueued for the same display - Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED); + Case::Display::injectPendingHotplugEvent(this, + HWComposer::HotplugEvent::Disconnected); // -------------------------------------------------------------------- // Call Expectations @@ -355,9 +352,10 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugConnectThenDisconnectPrimar EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID)); // SF should not have a PhysicalDisplay. - const auto displayId = Case::Display::DISPLAY_ID::get(); - ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId)); - ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(displayId)); + const auto physicalDisplayIdOpt = + asPhysicalDisplayId(Case::Display::DISPLAY_ID::get()); + ASSERT_TRUE(physicalDisplayIdOpt); + ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(*physicalDisplayIdOpt)); }(), testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected."); } @@ -378,9 +376,10 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectThenConnectPrimar existing.inject(); // A hotplug disconnect event is enqueued for a display - Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED); + Case::Display::injectPendingHotplugEvent(this, + HWComposer::HotplugEvent::Disconnected); // A hotplug connect event is also enqueued for the same display - Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED); + Case::Display::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); // -------------------------------------------------------------------- // Call Expectations @@ -398,10 +397,12 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectThenConnectPrimar // The existing token should have been removed. verifyDisplayIsNotConnected(existing.token()); - const auto displayId = Case::Display::DISPLAY_ID::get(); - ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId)); + const auto physicalDisplayIdOpt = + asPhysicalDisplayId(Case::Display::DISPLAY_ID::get()); + ASSERT_TRUE(physicalDisplayIdOpt); - const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(displayId); + const auto displayOpt = + mFlinger.mutablePhysicalDisplays().get(*physicalDisplayIdOpt); ASSERT_TRUE(displayOpt); EXPECT_NE(existing.token(), displayOpt->get().token()); @@ -538,9 +539,9 @@ TEST_F(DisplayTransactionCommitTest, processesVirtualDisplayRemoval) { // Preconditions // A virtual display is set up but is removed from the current state. - const auto displayId = Case::Display::DISPLAY_ID::get(); - ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId)); - mFlinger.mutableHwcDisplayData().try_emplace(displayId); + const auto displayId = asHalDisplayId(Case::Display::DISPLAY_ID::get()); + ASSERT_TRUE(displayId); + mFlinger.mutableHwcDisplayData().try_emplace(*displayId); Case::Display::injectHwcDisplay(this); auto existing = Case::Display::makeFakeExistingDisplayInjector(this); existing.inject(); diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp index 19f8debe84..8972840c8a 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp @@ -38,30 +38,30 @@ TEST_F(FoldableTest, promotesPacesetterOnBoot) { ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); // ...and should still be after powering on. - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); } TEST_F(FoldableTest, promotesPacesetterOnFoldUnfold) { - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); // The outer display should become the pacesetter after folding. - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::OFF); - mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(mOuterDisplay, PowerMode::ON); ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kOuterDisplayId); // The inner display should become the pacesetter after unfolding. - mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::OFF); - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mOuterDisplay, PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); } TEST_F(FoldableTest, promotesPacesetterOnConcurrentPowerOn) { - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); // The inner display should stay the pacesetter if both are powered on. // TODO(b/255635821): The pacesetter should depend on the displays' refresh rates. - mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mOuterDisplay, PowerMode::ON); ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); // The outer display should become the pacesetter if designated. @@ -74,20 +74,20 @@ TEST_F(FoldableTest, promotesPacesetterOnConcurrentPowerOn) { } TEST_F(FoldableTest, promotesPacesetterOnConcurrentPowerOff) { - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); - mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mOuterDisplay, PowerMode::ON); // The outer display should become the pacesetter if the inner display powers off. - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::OFF); ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kOuterDisplayId); // The outer display should stay the pacesetter if both are powered on. // TODO(b/255635821): The pacesetter should depend on the displays' refresh rates. - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kOuterDisplayId); // The inner display should become the pacesetter if the outer display powers off. - mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(mOuterDisplay, PowerMode::OFF); ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); } @@ -114,8 +114,8 @@ TEST_F(FoldableTest, requestsHardwareVsyncForInnerDisplay) { .Times(0); // The injected VsyncSchedule uses TestableScheduler::mockRequestHardwareVsync, so no calls to - // ISchedulerCallback::requestHardwareVsync are expected during setPowerModeInternal. - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); + // ISchedulerCallback::requestHardwareVsync are expected during setPhysicalDisplayPowerMode. + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); EXPECT_TRUE(mInnerDisplay->isPoweredOn()); EXPECT_FALSE(mOuterDisplay->isPoweredOn()); @@ -133,10 +133,10 @@ TEST_F(FoldableTest, requestsHardwareVsyncForOuterDisplay) { .Times(1); // The injected VsyncSchedule uses TestableScheduler::mockRequestHardwareVsync, so no calls to - // ISchedulerCallback::requestHardwareVsync are expected during setPowerModeInternal. - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::OFF); - mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + // ISchedulerCallback::requestHardwareVsync are expected during setPhysicalDisplayPowerMode. + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(mOuterDisplay, PowerMode::ON); EXPECT_FALSE(mInnerDisplay->isPoweredOn()); EXPECT_TRUE(mOuterDisplay->isPoweredOn()); @@ -154,9 +154,9 @@ TEST_F(FoldableTest, requestsHardwareVsyncForBothDisplays) { .Times(1); // The injected VsyncSchedule uses TestableScheduler::mockRequestHardwareVsync, so no calls to - // ISchedulerCallback::requestHardwareVsync are expected during setPowerModeInternal. - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); - mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + // ISchedulerCallback::requestHardwareVsync are expected during setPhysicalDisplayPowerMode. + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mOuterDisplay, PowerMode::ON); EXPECT_TRUE(mInnerDisplay->isPoweredOn()); EXPECT_TRUE(mOuterDisplay->isPoweredOn()); @@ -167,18 +167,16 @@ TEST_F(FoldableTest, requestsHardwareVsyncForBothDisplays) { } TEST_F(FoldableTest, requestVsyncOnPowerOn) { - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); EXPECT_CALL(mFlinger.scheduler()->mockRequestHardwareVsync, Call(kInnerDisplayId, true)) .Times(1); EXPECT_CALL(mFlinger.scheduler()->mockRequestHardwareVsync, Call(kOuterDisplayId, true)) .Times(1); - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); - mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mOuterDisplay, PowerMode::ON); } TEST_F(FoldableTest, disableVsyncOnPowerOffPacesetter) { - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); // When the device boots, the inner display should be the pacesetter. ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId); @@ -192,10 +190,10 @@ TEST_F(FoldableTest, disableVsyncOnPowerOffPacesetter) { EXPECT_CALL(mFlinger.scheduler()->mockRequestHardwareVsync, Call(kInnerDisplayId, false)) .Times(1); - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON); - mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(mOuterDisplay, PowerMode::ON); - mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(mInnerDisplay, PowerMode::OFF); // Other display is now the pacesetter. ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kOuterDisplayId); diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp index 4e7a1742fd..b8b1b9527c 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp @@ -41,9 +41,9 @@ TEST_F(HotplugTest, schedulesConfigureToProcessHotplugEvents) { const auto& pendingEvents = mFlinger.mutablePendingHotplugEvents(); ASSERT_EQ(2u, pendingEvents.size()); EXPECT_EQ(hwcDisplayId1, pendingEvents[0].hwcDisplayId); - EXPECT_EQ(Connection::CONNECTED, pendingEvents[0].connection); + EXPECT_EQ(HWComposer::HotplugEvent::Connected, pendingEvents[0].event); EXPECT_EQ(hwcDisplayId2, pendingEvents[1].hwcDisplayId); - EXPECT_EQ(Connection::DISCONNECTED, pendingEvents[1].connection); + EXPECT_EQ(HWComposer::HotplugEvent::Disconnected, pendingEvents[1].event); } TEST_F(HotplugTest, schedulesFrameToCommitDisplayTransaction) { @@ -64,9 +64,9 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) { using PrimaryDisplay = InnerDisplayVariant; PrimaryDisplay::setupHwcHotplugCallExpectations(this); PrimaryDisplay::setupHwcGetActiveConfigCallExpectations(this); - PrimaryDisplay::injectPendingHotplugEvent(this, Connection::CONNECTED); + PrimaryDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); - // TODO(b/241286146): Remove this unnecessary call. + // TODO: b/241286146 - Remove this unnecessary call. EXPECT_CALL(*mComposer, setVsyncEnabled(PrimaryDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) .WillOnce(Return(Error::NONE)); @@ -77,12 +77,12 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) { mFlinger.configure(); // Configure an external display with identification info. - using ExternalDisplay = ExternalDisplayWithIdentificationVariant; + using ExternalDisplay = ExternalDisplayWithIdentificationVariant<>; ExternalDisplay::setupHwcHotplugCallExpectations(this); ExternalDisplay::setupHwcGetActiveConfigCallExpectations(this); - ExternalDisplay::injectPendingHotplugEvent(this, Connection::CONNECTED); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); - // TODO(b/241286146): Remove this unnecessary call. + // TODO: b/241286146 - Remove this unnecessary call. EXPECT_CALL(*mComposer, setVsyncEnabled(ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) .WillOnce(Return(Error::NONE)); @@ -90,7 +90,9 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) { mFlinger.configure(); EXPECT_TRUE(hasPhysicalHwcDisplay(PrimaryDisplay::HWC_DISPLAY_ID)); - EXPECT_TRUE(mFlinger.getHwComposer().isConnected(PrimaryDisplay::DISPLAY_ID::get())); + const auto primaryDisplayId = asPhysicalDisplayId(PrimaryDisplay::DISPLAY_ID::get()); + ASSERT_TRUE(primaryDisplayId); + EXPECT_TRUE(mFlinger.getHwComposer().isConnected(*primaryDisplayId)); const auto primaryDisplayIdOpt = mFlinger.getHwComposer().toPhysicalDisplayId(PrimaryDisplay::HWC_DISPLAY_ID); ASSERT_TRUE(primaryDisplayIdOpt.has_value()); @@ -98,13 +100,15 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) { mFlinger.physicalDisplays().get(primaryDisplayIdOpt.value()); ASSERT_TRUE(primaryPhysicalDisplayOpt.has_value()); const auto primaryDisplaySnapshotRef = primaryPhysicalDisplayOpt->get().snapshotRef(); - EXPECT_EQ(PrimaryDisplay::DISPLAY_ID::get(), primaryDisplaySnapshotRef.get().displayId()); + EXPECT_EQ(*primaryDisplayId, primaryDisplaySnapshotRef.get().displayId()); EXPECT_EQ(PrimaryDisplay::PORT::value, primaryDisplaySnapshotRef.get().port()); EXPECT_EQ(PrimaryDisplay::CONNECTION_TYPE::value, primaryDisplaySnapshotRef.get().connectionType()); EXPECT_TRUE(hasPhysicalHwcDisplay(ExternalDisplay::HWC_DISPLAY_ID)); - EXPECT_TRUE(mFlinger.getHwComposer().isConnected(ExternalDisplay::DISPLAY_ID::get())); + const auto externalDisplayId = asPhysicalDisplayId(ExternalDisplay::DISPLAY_ID::get()); + ASSERT_TRUE(externalDisplayId); + EXPECT_TRUE(mFlinger.getHwComposer().isConnected(*externalDisplayId)); const auto externalDisplayIdOpt = mFlinger.getHwComposer().toPhysicalDisplayId(ExternalDisplay::HWC_DISPLAY_ID); ASSERT_TRUE(externalDisplayIdOpt.has_value()); @@ -112,7 +116,7 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) { mFlinger.physicalDisplays().get(externalDisplayIdOpt.value()); ASSERT_TRUE(externalPhysicalDisplayOpt.has_value()); const auto externalDisplaySnapshotRef = externalPhysicalDisplayOpt->get().snapshotRef(); - EXPECT_EQ(ExternalDisplay::DISPLAY_ID::get(), externalDisplaySnapshotRef.get().displayId()); + EXPECT_EQ(*externalDisplayId, externalDisplaySnapshotRef.get().displayId()); EXPECT_EQ(ExternalDisplay::PORT::value, externalDisplaySnapshotRef.get().port()); EXPECT_EQ(ExternalDisplay::CONNECTION_TYPE::value, externalDisplaySnapshotRef.get().connectionType()); @@ -123,9 +127,9 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithoutIdentificationData) using PrimaryDisplay = PrimaryDisplayVariant; PrimaryDisplay::setupHwcHotplugCallExpectations(this); PrimaryDisplay::setupHwcGetActiveConfigCallExpectations(this); - PrimaryDisplay::injectPendingHotplugEvent(this, Connection::CONNECTED); + PrimaryDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); - // TODO(b/241286146): Remove this unnecessary call. + // TODO: b/241286146 - Remove this unnecessary call. EXPECT_CALL(*mComposer, setVsyncEnabled(PrimaryDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) .WillOnce(Return(Error::NONE)); @@ -136,12 +140,12 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithoutIdentificationData) mFlinger.configure(); // Configure an external display with identification info. - using ExternalDisplay = ExternalDisplayWithIdentificationVariant; + using ExternalDisplay = ExternalDisplayWithIdentificationVariant<>; ExternalDisplay::setupHwcHotplugCallExpectations(this); ExternalDisplay::setupHwcGetActiveConfigCallExpectations(this); - ExternalDisplay::injectPendingHotplugEvent(this, Connection::CONNECTED); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); - // TODO(b/241286146): Remove this unnecessary call. + // TODO: b/241286146 - Remove this unnecessary call. EXPECT_CALL(*mComposer, setVsyncEnabled(ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) .WillOnce(Return(Error::NONE)); @@ -154,8 +158,8 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithoutIdentificationData) constexpr PhysicalDisplayId primaryInternalDisplayId = PhysicalDisplayId::fromPort(primaryInternalDisplayPort); EXPECT_TRUE(hasPhysicalHwcDisplay(PrimaryDisplay::HWC_DISPLAY_ID)); - ASSERT_EQ(primaryInternalDisplayId, PrimaryDisplay::DISPLAY_ID::get()); - EXPECT_TRUE(mFlinger.getHwComposer().isConnected(PrimaryDisplay::DISPLAY_ID::get())); + ASSERT_EQ(primaryInternalDisplayId, asPhysicalDisplayId(PrimaryDisplay::DISPLAY_ID::get())); + EXPECT_TRUE(mFlinger.getHwComposer().isConnected(primaryInternalDisplayId)); const auto primaryDisplayIdOpt = mFlinger.getHwComposer().toPhysicalDisplayId(PrimaryDisplay::HWC_DISPLAY_ID); ASSERT_TRUE(primaryDisplayIdOpt.has_value()); @@ -198,7 +202,7 @@ TEST_F(HotplugTest, ignoresDuplicateDisconnection) { ExternalDisplay::setupHwcHotplugCallExpectations(this); ExternalDisplay::setupHwcGetActiveConfigCallExpectations(this); - // TODO(b/241286146): Remove this unnecessary call. + // TODO: b/241286146 - Remove this unnecessary call. EXPECT_CALL(*mComposer, setVsyncEnabled(ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) .WillOnce(Return(Error::NONE)); @@ -206,26 +210,26 @@ TEST_F(HotplugTest, ignoresDuplicateDisconnection) { // A single commit should be scheduled for both configure calls. EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1); - ExternalDisplay::injectPendingHotplugEvent(this, Connection::CONNECTED); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); mFlinger.configure(); EXPECT_TRUE(hasPhysicalHwcDisplay(ExternalDisplay::HWC_DISPLAY_ID)); // Disconnecting a display that was already disconnected should be a no-op. - ExternalDisplay::injectPendingHotplugEvent(this, Connection::DISCONNECTED); - ExternalDisplay::injectPendingHotplugEvent(this, Connection::DISCONNECTED); - ExternalDisplay::injectPendingHotplugEvent(this, Connection::DISCONNECTED); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Disconnected); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Disconnected); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Disconnected); mFlinger.configure(); // The display should be scheduled for removal during the next commit. At this point, it should // still exist but be marked as disconnected. EXPECT_TRUE(hasPhysicalHwcDisplay(ExternalDisplay::HWC_DISPLAY_ID)); - EXPECT_FALSE(mFlinger.getHwComposer().isConnected(ExternalDisplay::DISPLAY_ID::get())); + const auto externalDisplayId = asPhysicalDisplayId(ExternalDisplay::DISPLAY_ID::get()); + ASSERT_TRUE(externalDisplayId); + EXPECT_FALSE(mFlinger.getHwComposer().isConnected(*externalDisplayId)); } TEST_F(HotplugTest, rejectsHotplugIfFailedToLoadDisplayModes) { - SET_FLAG_FOR_TEST(flags::connected_display, true); - // Inject a primary display. PrimaryDisplayVariant::injectHwcDisplay(this); @@ -242,24 +246,71 @@ TEST_F(HotplugTest, rejectsHotplugIfFailedToLoadDisplayModes) { EXPECT_CALL(*mComposer, getActiveConfig(ExternalDisplay::HWC_DISPLAY_ID, _)) .WillRepeatedly(Return(Error::BAD_DISPLAY)); - // TODO(b/241286146): Remove this unnecessary call. + // TODO: b/241286146 - Remove this unnecessary call. EXPECT_CALL(*mComposer, setVsyncEnabled(ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) .WillOnce(Return(Error::NONE)); EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1); - ExternalDisplay::injectPendingHotplugEvent(this, Connection::CONNECTED); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); mFlinger.configure(); // The hotplug should be rejected, so no HWComposer::DisplayData should be created. EXPECT_FALSE(hasPhysicalHwcDisplay(ExternalDisplay::HWC_DISPLAY_ID)); // Disconnecting a display that does not exist should be a no-op. - ExternalDisplay::injectPendingHotplugEvent(this, Connection::DISCONNECTED); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Disconnected); mFlinger.configure(); EXPECT_FALSE(hasPhysicalHwcDisplay(ExternalDisplay::HWC_DISPLAY_ID)); } +TEST_F(HotplugTest, rejectsHotplugOnActivePortsDuplicate) { + // Inject a primary display. + PrimaryDisplayVariant::injectHwcDisplay(this); + + // Second display should come up properly. + using SecondDisplay = ExternalDisplayWithIdentificationVariant<>; + SecondDisplay::setupHwcHotplugCallExpectations(this); + SecondDisplay::setupHwcGetActiveConfigCallExpectations(this); + + // TODO: b/241286146 - Remove this unnecessary call. + EXPECT_CALL(*mComposer, + setVsyncEnabled(SecondDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) + .WillOnce(Return(Error::NONE)); + + EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1); + + SecondDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); + mFlinger.configure(); + + EXPECT_TRUE(hasPhysicalHwcDisplay(SecondDisplay::HWC_DISPLAY_ID)); + + // Third display will return the same port ID as the second, and the hotplug + // should fail. + constexpr HWDisplayId kHwDisplayId = 1234; + using DuplicatePortDisplay = ExternalDisplayWithIdentificationVariant<kHwDisplayId>; + + // We expect display identification to be fetched correctly, since EDID and + // port are available and successfully retrieved from HAL. + EXPECT_CALL(*mComposer, + getDisplayIdentificationData(DuplicatePortDisplay::HWC_DISPLAY_ID, _, _)) + .WillOnce(DoAll(SetArgPointee<1>(*DuplicatePortDisplay::PORT::value), + SetArgPointee<2>(getExternalEedid()), Return(Error::NONE))); + + DuplicatePortDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); + mFlinger.configure(); + + // The hotplug should be rejected due to an attempt to connect a display to an already active + // port. No HWComposer::DisplayData should be created. + EXPECT_FALSE(hasPhysicalHwcDisplay(DuplicatePortDisplay::HWC_DISPLAY_ID)); + + // Disconnecting a display that was not successfully configured should be a no-op. + DuplicatePortDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Disconnected); + mFlinger.configure(); + + EXPECT_FALSE(hasPhysicalHwcDisplay(DuplicatePortDisplay::HWC_DISPLAY_ID)); +} + } // namespace android diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp index 6cc6322bfc..9c143fdd41 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp @@ -45,28 +45,15 @@ protected: void setTransactionState() { ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty()); TransactionInfo transaction; - mFlinger.setTransactionState(FrameTimelineInfo{}, transaction.states, transaction.displays, - transaction.flags, transaction.applyToken, - transaction.inputWindowCommands, - TimePoint::now().ns() + s2ns(1), transaction.isAutoTimestamp, - transaction.unCachedBuffers, - /*HasListenerCallbacks=*/false, transaction.callbacks, - transaction.id, transaction.mergedTransactionIds); + mFlinger.setTransactionState(std::move(transaction)); } - struct TransactionInfo { - Vector<ComposerState> states; - Vector<DisplayState> displays; - uint32_t flags = 0; - sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); - InputWindowCommands inputWindowCommands; - int64_t desiredPresentTime = 0; - bool isAutoTimestamp = false; - FrameTimelineInfo frameTimelineInfo{}; - std::vector<client_cache_t> unCachedBuffers; - uint64_t id = static_cast<uint64_t>(-1); - std::vector<uint64_t> mergedTransactionIds; - std::vector<ListenerCallbacks> callbacks; + struct TransactionInfo : public TransactionState { + TransactionInfo() { + mApplyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); + mIsAutoTimestamp = false; + mId = static_cast<uint64_t>(-1); + } }; struct Compositor final : ICompositor { @@ -383,4 +370,4 @@ TEST_F(NotifyExpectedPresentTest, notifyExpectedPresentRenderRateChanged) { } } } -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPhysicalDisplayPowerModeTest.cpp index fed7b2e767..d5c22a9601 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPhysicalDisplayPowerModeTest.cpp @@ -315,7 +315,7 @@ using ExternalDisplayPowerCase = EventThreadNotSupportedVariant, DispSyncNotSupportedVariant, TransitionVariant>; -class SetPowerModeInternalTest : public DisplayTransactionTest { +class SetPhysicalDisplayPowerModeTest : public DisplayTransactionTest { public: template <typename Case> void transitionDisplayCommon(); @@ -331,15 +331,14 @@ template <> struct PowerModeInitialVSyncEnabled<PowerMode::DOZE> : public std::true_type {}; template <typename Case> -void SetPowerModeInternalTest::transitionDisplayCommon() { +void SetPhysicalDisplayPowerModeTest::transitionDisplayCommon() { // -------------------------------------------------------------------- // Preconditions Case::Doze::setupComposerCallExpectations(this); auto display = Case::injectDisplayWithInitialPowerMode(this, Case::Transition::INITIAL_POWER_MODE); - auto displayId = display->getId(); - if (auto physicalDisplayId = PhysicalDisplayId::tryCast(displayId)) { + if (auto physicalDisplayId = asPhysicalDisplayId(display->getDisplayIdVariant())) { Case::setInitialHwVsyncEnabled(this, *physicalDisplayId, PowerModeInitialVSyncEnabled< Case::Transition::INITIAL_POWER_MODE>::value); @@ -353,7 +352,7 @@ void SetPowerModeInternalTest::transitionDisplayCommon() { // -------------------------------------------------------------------- // Invocation - mFlinger.setPowerModeInternal(display, Case::Transition::TARGET_POWER_MODE); + mFlinger.setPhysicalDisplayPowerMode(display, Case::Transition::TARGET_POWER_MODE); // -------------------------------------------------------------------- // Postconditions @@ -361,7 +360,7 @@ void SetPowerModeInternalTest::transitionDisplayCommon() { Case::Transition::verifyPostconditions(this); } -TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfNoChange) { +TEST_F(SetPhysicalDisplayPowerModeTest, setPhysicalDisplayPowerModeDoesNothingIfNoChange) { using Case = SimplePrimaryDisplayCase; // -------------------------------------------------------------------- @@ -378,7 +377,7 @@ TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfNoChange) { // -------------------------------------------------------------------- // Invocation - mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), PowerMode::ON); + mFlinger.setPhysicalDisplayPowerMode(display.mutableDisplayDevice(), PowerMode::ON); // -------------------------------------------------------------------- // Postconditions @@ -386,16 +385,16 @@ TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfNoChange) { EXPECT_EQ(PowerMode::ON, display.mutableDisplayDevice()->getPowerMode()); } -TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfVirtualDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, setPhysicalDisplayPowerModeDoesNothingIfVirtualDisplay) { using Case = HwcVirtualDisplayCase; // -------------------------------------------------------------------- // Preconditions // Insert display data so that the HWC thinks it created the virtual display. - const auto displayId = Case::Display::DISPLAY_ID::get(); - ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId)); - mFlinger.mutableHwcDisplayData().try_emplace(displayId); + const auto displayId = asHalDisplayId(Case::Display::DISPLAY_ID::get()); + ASSERT_TRUE(displayId); + ASSERT_TRUE(mFlinger.mutableHwcDisplayData().try_emplace(*displayId).second); // A virtual display device is set up Case::Display::injectHwcDisplay(this); @@ -408,7 +407,7 @@ TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfVirtualDisplay // -------------------------------------------------------------------- // Invocation - mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), PowerMode::OFF); + mFlinger.setPhysicalDisplayPowerMode(display.mutableDisplayDevice(), PowerMode::OFF); // -------------------------------------------------------------------- // Postconditions @@ -416,88 +415,83 @@ TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfVirtualDisplay EXPECT_EQ(PowerMode::ON, display.mutableDisplayDevice()->getPowerMode()); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnPrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOffToOnPrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToOnVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendPrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOffToDozeSuspendPrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToDozeSuspendVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffPrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToOffPrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToOffVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffPrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeSuspendToOffPrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOffVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozePrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToDozePrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozePrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeSuspendToDozePrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnPrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeToOnPrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeToOnVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnPrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeSuspendToOnPrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOnVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendPrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToDozeSuspendPrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeSuspendVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownPrimaryDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToUnknownPrimaryDisplay) { transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToUnknownVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnExternalDisplay) { - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOffToOnExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToOnVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendExternalDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOffToDozeSuspendExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToDozeSuspendVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffExternalDisplay) { - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToOffExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToOffVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffExternalDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeSuspendToOffExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOffVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeExternalDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToDozeExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozeExternalDisplay) { - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeSuspendToDozeExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnExternalDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeToOnExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeToOnVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnExternalDisplay) { - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeSuspendToOnExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOnVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendExternalDisplay) { - SET_FLAG_FOR_TEST(flags::multithreaded_present, true); +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToDozeSuspendExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeSuspendVariant>>(); } -TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownExternalDisplay) { +TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToUnknownExternalDisplay) { transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToUnknownVariant>>(); } diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp index 6951eaf093..23e73de660 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp @@ -235,13 +235,14 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() { constexpr auto kConnectionTypeOpt = Case::Display::CONNECTION_TYPE::value; if constexpr (kConnectionTypeOpt) { - const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get()); + const auto displayId = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get()); ASSERT_TRUE(displayId); const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value; ASSERT_TRUE(hwcDisplayId); const auto port = Case::Display::PORT::value; ASSERT_TRUE(port); - mFlinger.getHwComposer().allocatePhysicalDisplay(*hwcDisplayId, *displayId, std::nullopt); + mFlinger.getHwComposer().allocatePhysicalDisplay(*hwcDisplayId, *displayId, *port, + std::nullopt); DisplayModePtr activeMode = DisplayMode::Builder(Case::Display::HWC_ACTIVE_CONFIG_ID) .setResolution(Case::Display::RESOLUTION) .setVsyncPeriod(DEFAULT_VSYNC_PERIOD) @@ -252,6 +253,7 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() { state.physical = {.id = *displayId, .hwcDisplayId = *hwcDisplayId, + .port = *port, .activeMode = activeMode}; ui::ColorModes colorModes; @@ -280,7 +282,7 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() { // Postconditions ASSERT_NE(nullptr, device); - EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getId()); + EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getDisplayIdVariant()); EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), device->isVirtual()); EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure()); EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary()); diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 3455c13bb7..13c32bdf08 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -42,7 +42,6 @@ #include "FrontEnd/RequestedLayerState.h" #include "Layer.h" #include "NativeWindowSurface.h" -#include "RenderArea.h" #include "Scheduler/RefreshRateSelector.h" #include "Scheduler/VSyncTracker.h" #include "Scheduler/VsyncController.h" @@ -184,8 +183,8 @@ public: } void setupComposer(std::unique_ptr<Hwc2::Composer> composer) { - mFlinger->mCompositionEngine->setHwComposer( - std::make_unique<impl::HWComposer>(std::move(composer))); + mFlinger->mHWComposer = std::make_unique<impl::HWComposer>(std::move(composer)); + mFlinger->mCompositionEngine->setHwComposer(mFlinger->mHWComposer.get()); mFlinger->mDisplayModeController.setHwComposer( &mFlinger->mCompositionEngine->getHwComposer()); } @@ -338,9 +337,9 @@ public: mFlinger->configure(); } - void configureAndCommit() { + void configureAndCommit(bool modeset = false) { configure(); - commitTransactionsLocked(eDisplayTransactionNeeded); + commitTransactionsLocked(eDisplayTransactionNeeded, modeset); } void commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expectedVsyncTime, @@ -400,12 +399,16 @@ public: float requestedRefreshRate = 0.0f) { static const std::string kTestId = "virtual:libsurfaceflinger_unittest:TestableSurfaceFlinger"; - return mFlinger->createVirtualDisplay(displayName, isSecure, kTestId, requestedRefreshRate); + return mFlinger + ->createVirtualDisplay(displayName, isSecure, + gui::ISurfaceComposer::OptimizationPolicy::optimizeForPower, + kTestId, requestedRefreshRate); } auto createVirtualDisplay(const std::string& displayName, bool isSecure, + gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy, const std::string& uniqueId, float requestedRefreshRate = 0.0f) { - return mFlinger->createVirtualDisplay(displayName, isSecure, uniqueId, + return mFlinger->createVirtualDisplay(displayName, isSecure, optimizationPolicy, uniqueId, requestedRefreshRate); } @@ -430,11 +433,14 @@ public: dispSurface, producer); } - void commitTransactionsLocked(uint32_t transactionFlags) { + void commitTransactionsLocked(uint32_t transactionFlags, bool modeset = false) { Mutex::Autolock lock(mFlinger->mStateLock); ftl::FakeGuard guard(kMainThreadContext); mFlinger->processDisplayChangesLocked(); mFlinger->commitTransactionsLocked(transactionFlags); + if (modeset) { + mFlinger->initiateDisplayModeChanges(); + } } void onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId, DisplayHotplugEvent event) { @@ -456,26 +462,39 @@ public: } // Allow reading display state without locking, as if called on the SF main thread. - auto setPowerModeInternal(const sp<DisplayDevice>& display, - hal::PowerMode mode) NO_THREAD_SAFETY_ANALYSIS { - return mFlinger->setPowerModeInternal(display, mode); + auto setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, + hal::PowerMode mode) NO_THREAD_SAFETY_ANALYSIS { + return mFlinger->setPhysicalDisplayPowerMode(display, mode); } - auto renderScreenImpl(const sp<DisplayDevice> display, - std::unique_ptr<const RenderArea> renderArea, + auto renderScreenImpl(const sp<DisplayDevice> display, const Rect sourceCrop, + ui::Dataspace dataspace, SurfaceFlinger::GetLayerSnapshotsFunction getLayerSnapshotsFn, const std::shared_ptr<renderengine::ExternalTexture>& buffer, - bool regionSampling) { + bool regionSampling, bool isSecure, bool seamlessTransition) { Mutex::Autolock lock(mFlinger->mStateLock); ftl::FakeGuard guard(kMainThreadContext); ScreenCaptureResults captureResults; - auto displayState = std::optional{display->getCompositionDisplay()->getState()}; + const auto& state = display->getCompositionDisplay()->getState(); auto layers = getLayerSnapshotsFn(); - return mFlinger->renderScreenImpl(renderArea.get(), buffer, regionSampling, + SurfaceFlinger::ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = display; + screenshotArgs.displayIdVariant = std::nullopt; + screenshotArgs.sourceCrop = sourceCrop; + screenshotArgs.reqSize = sourceCrop.getSize(); + screenshotArgs.dataspace = dataspace; + screenshotArgs.isSecure = isSecure; + screenshotArgs.seamlessTransition = seamlessTransition; + screenshotArgs.displayBrightnessNits = state.displayBrightnessNits; + screenshotArgs.sdrWhitePointNits = state.sdrWhitePointNits; + screenshotArgs.renderIntent = state.renderIntent; + screenshotArgs.colorMode = state.colorMode; + + return mFlinger->renderScreenImpl(screenshotArgs, buffer, regionSampling, false /* grayscale */, false /* isProtected */, - captureResults, displayState, layers); + captureResults, layers); } auto getLayerSnapshotsForScreenshotsFn(ui::LayerStack layerStack, uint32_t uid) { @@ -500,18 +519,8 @@ public: return mFlinger->mTransactionHandler.mPendingTransactionCount.load(); } - auto setTransactionState( - const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states, - Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, - bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, - bool hasListenerCallbacks, std::vector<ListenerCallbacks>& listenerCallbacks, - uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) { - return mFlinger->setTransactionState(frameTimelineInfo, states, displays, flags, applyToken, - inputWindowCommands, desiredPresentTime, - isAutoTimestamp, uncacheBuffers, hasListenerCallbacks, - listenerCallbacks, transactionId, - mergedTransactionIds); + auto setTransactionState(TransactionState&& state) { + return mFlinger->setTransactionState(std::move(state)); } auto setTransactionStateInternal(QueuedTransactionState& transaction) { @@ -564,7 +573,7 @@ public: } sp<DisplayDevice> createVirtualDisplayDevice(const sp<IBinder> displayToken, - VirtualDisplayId displayId, + GpuVirtualDisplayId displayId, float requestedRefreshRate) { constexpr ui::Size kResolution = {1080, 1920}; auto compositionDisplay = compositionengine::impl:: @@ -701,6 +710,7 @@ public: } auto& mutableMinAcquiredBuffers() { return SurfaceFlinger::minAcquiredBuffers; } + auto& mutableMaxAcquiredBuffers() { return SurfaceFlinger::maxAcquiredBuffersOpt; } auto& mutableLayerSnapshotBuilder() NO_THREAD_SAFETY_ANALYSIS { return mFlinger->mLayerSnapshotBuilder; } @@ -771,7 +781,8 @@ public: mutableCurrentState().displays.clear(); mutableDrawingState().displays.clear(); mFlinger->mScheduler.reset(); - mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>()); + mFlinger->mHWComposer = std::unique_ptr<HWComposer>(); + mFlinger->mCompositionEngine->setHwComposer(mFlinger->mHWComposer.get()); mFlinger->mRenderEngine = std::unique_ptr<renderengine::RenderEngine>(); mFlinger->mCompositionEngine->setRenderEngine(mFlinger->mRenderEngine.get()); mFlinger->mTransactionTracing.reset(); @@ -806,9 +817,11 @@ public: static constexpr int32_t DEFAULT_DPI = 320; static constexpr hal::HWConfigId DEFAULT_ACTIVE_CONFIG = 0; - FakeHwcDisplayInjector(HalDisplayId displayId, hal::DisplayType hwcDisplayType, + FakeHwcDisplayInjector(DisplayIdVariant displayIdVariant, hal::DisplayType hwcDisplayType, bool isPrimary) - : mDisplayId(displayId), mHwcDisplayType(hwcDisplayType), mIsPrimary(isPrimary) {} + : mDisplayIdVariant(displayIdVariant), + mHwcDisplayType(hwcDisplayType), + mIsPrimary(isPrimary) {} auto& setHwcDisplayId(hal::HWDisplayId displayId) { mHwcDisplayId = displayId; @@ -873,7 +886,9 @@ public: display->setPowerMode(mPowerMode); - flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = std::move(display); + const auto halDisplayId = asHalDisplayId(mDisplayIdVariant); + ASSERT_TRUE(halDisplayId); + flinger->mutableHwcDisplayData()[*halDisplayId].hwcDisplay = std::move(display); EXPECT_CALL(*composer, getDisplayConfigs(mHwcDisplayId, _)) .WillRepeatedly( @@ -911,9 +926,10 @@ public: DoAll(SetArgPointee<3>(mConfigGroup), Return(hal::Error::NONE))); if (mHwcDisplayType == hal::DisplayType::PHYSICAL) { - const auto physicalId = PhysicalDisplayId::tryCast(mDisplayId); - LOG_ALWAYS_FATAL_IF(!physicalId); - flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, *physicalId); + const auto physicalDisplayId = asPhysicalDisplayId(mDisplayIdVariant); + ASSERT_TRUE(physicalDisplayId); + flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, + *physicalDisplayId); if (mIsPrimary) { flinger->mutablePrimaryHwcDisplayId() = mHwcDisplayId; } else { @@ -926,7 +942,7 @@ public: } private: - const HalDisplayId mDisplayId; + const DisplayIdVariant mDisplayIdVariant; const hal::DisplayType mHwcDisplayType; const bool mIsPrimary; @@ -962,8 +978,8 @@ public: sp<IBinder> token() const { return mDisplayToken; } auto physicalDisplay() const { - return ftl::Optional(mCreationArgs.compositionDisplay->getDisplayId()) - .and_then(&PhysicalDisplayId::tryCast) + return mCreationArgs.compositionDisplay->getDisplayIdVariant() + .and_then(asPhysicalDisplayId) .and_then(display::getPhysicalDisplay(mFlinger.physicalDisplays())); } @@ -1061,7 +1077,9 @@ public: DisplayDeviceState state; state.isSecure = mCreationArgs.isSecure; - if (const auto physicalId = PhysicalDisplayId::tryCast(*displayId)) { + if (const auto physicalId = + mCreationArgs.compositionDisplay->getDisplayIdVariant().and_then( + asPhysicalDisplayId)) { LOG_ALWAYS_FATAL_IF(!mConnectionType); LOG_ALWAYS_FATAL_IF(!mHwcDisplayId); diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp index 69dfcc4a8f..6a5ac2a70e 100644 --- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp @@ -17,6 +17,8 @@ #undef LOG_TAG #define LOG_TAG "TransactionApplicationTest" +#include <cstdint> + #include <binder/Binder.h> #include <common/test/FlagUtils.h> #include <compositionengine/Display.h> @@ -69,38 +71,32 @@ public: TestableSurfaceFlinger mFlinger; renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); - struct TransactionInfo { - Vector<ComposerState> states; - Vector<DisplayState> displays; - uint32_t flags = 0; - sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); - InputWindowCommands inputWindowCommands; - int64_t desiredPresentTime = 0; - bool isAutoTimestamp = true; - FrameTimelineInfo frameTimelineInfo; - std::vector<client_cache_t> uncacheBuffers; - uint64_t id = static_cast<uint64_t>(-1); - std::vector<uint64_t> mergedTransactionIds; - static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1)); + struct TransactionInfo : public TransactionState { + TransactionInfo() { + mApplyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); + mId = static_cast<uint64_t>(-1); + } }; void checkEqual(TransactionInfo info, QueuedTransactionState state) { - EXPECT_EQ(0u, info.states.size()); + EXPECT_EQ(0u, info.mComposerStates.size()); EXPECT_EQ(0u, state.states.size()); - EXPECT_EQ(0u, info.displays.size()); + EXPECT_EQ(0u, info.mDisplayStates.size()); EXPECT_EQ(0u, state.displays.size()); - EXPECT_EQ(info.flags, state.flags); - EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime); + EXPECT_EQ(info.mFlags, state.flags); + EXPECT_EQ(info.mDesiredPresentTime, state.desiredPresentTime); } void setupSingle(TransactionInfo& transaction, uint32_t flags, int64_t desiredPresentTime, bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo) { mTransactionNumber++; - transaction.flags |= flags; - transaction.desiredPresentTime = desiredPresentTime; - transaction.isAutoTimestamp = isAutoTimestamp; - transaction.frameTimelineInfo = frameTimelineInfo; + transaction.mFlags |= flags; + transaction.mDesiredPresentTime = desiredPresentTime; + transaction.mIsAutoTimestamp = isAutoTimestamp; + transaction.mFrameTimelineInfo = frameTimelineInfo; + transaction.mHasListenerCallbacks = mHasListenerCallbacks; + transaction.mListenerCallbacks = mCallbacks; } void NotPlacedOnTransactionQueue(uint32_t flags) { @@ -111,12 +107,7 @@ public: /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true, FrameTimelineInfo{}); nsecs_t applicationTime = systemTime(); - mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states, - transaction.displays, transaction.flags, - transaction.applyToken, transaction.inputWindowCommands, - transaction.desiredPresentTime, transaction.isAutoTimestamp, - transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks, - transaction.id, transaction.mergedTransactionIds); + mFlinger.setTransactionState(std::move(transaction)); // If transaction is synchronous, SF applyTransactionState should time out (5s) wating for // SF to commit the transaction. If this is animation, it should not time out waiting. @@ -138,12 +129,7 @@ public: setupSingle(transaction, flags, /*desiredPresentTime*/ time + s2ns(1), false, FrameTimelineInfo{}); nsecs_t applicationSentTime = systemTime(); - mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states, - transaction.displays, transaction.flags, - transaction.applyToken, transaction.inputWindowCommands, - transaction.desiredPresentTime, transaction.isAutoTimestamp, - transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks, - transaction.id, transaction.mergedTransactionIds); + mFlinger.setTransactionState(std::move(transaction)); nsecs_t returnedTime = systemTime(); EXPECT_LE(returnedTime, applicationSentTime + TRANSACTION_TIMEOUT); @@ -169,12 +155,7 @@ public: /*isAutoTimestamp*/ true, FrameTimelineInfo{}); nsecs_t applicationSentTime = systemTime(); - mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states, - transactionA.displays, transactionA.flags, - transactionA.applyToken, transactionA.inputWindowCommands, - transactionA.desiredPresentTime, transactionA.isAutoTimestamp, - transactionA.uncacheBuffers, mHasListenerCallbacks, mCallbacks, - transactionA.id, transactionA.mergedTransactionIds); + mFlinger.setTransactionState(std::move(transactionA)); // This thread should not have been blocked by the above transaction // (5s is the timeout period that applyTransactionState waits for SF to @@ -184,12 +165,7 @@ public: mFlinger.flushTransactionQueues(); applicationSentTime = systemTime(); - mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states, - transactionB.displays, transactionB.flags, - transactionB.applyToken, transactionB.inputWindowCommands, - transactionB.desiredPresentTime, transactionB.isAutoTimestamp, - transactionB.uncacheBuffers, mHasListenerCallbacks, mCallbacks, - transactionB.id, transactionB.mergedTransactionIds); + mFlinger.setTransactionState(std::move(transactionB)); // this thread should have been blocked by the above transaction // if this is an animation, this thread should be blocked for 5s @@ -222,12 +198,7 @@ TEST_F(TransactionApplicationTest, AddToPendingQueue) { TransactionInfo transactionA; // transaction to go on pending queue setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false, FrameTimelineInfo{}); - mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states, - transactionA.displays, transactionA.flags, transactionA.applyToken, - transactionA.inputWindowCommands, transactionA.desiredPresentTime, - transactionA.isAutoTimestamp, transactionA.uncacheBuffers, - mHasListenerCallbacks, mCallbacks, transactionA.id, - transactionA.mergedTransactionIds); + mFlinger.setTransactionState(std::move(transactionA)); auto& transactionQueue = mFlinger.getTransactionQueue(); ASSERT_FALSE(transactionQueue.isEmpty()); @@ -243,12 +214,7 @@ TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) { TransactionInfo transactionA; // transaction to go on pending queue setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false, FrameTimelineInfo{}); - mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states, - transactionA.displays, transactionA.flags, transactionA.applyToken, - transactionA.inputWindowCommands, transactionA.desiredPresentTime, - transactionA.isAutoTimestamp, transactionA.uncacheBuffers, - mHasListenerCallbacks, mCallbacks, transactionA.id, - transactionA.mergedTransactionIds); + mFlinger.setTransactionState(std::move(transactionA)); auto& transactionQueue = mFlinger.getTransactionQueue(); ASSERT_FALSE(transactionQueue.isEmpty()); @@ -257,12 +223,10 @@ TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) { // transaction here (sending a null applyToken to fake it as from a // different process) to re-query and reset the cached expected present time TransactionInfo empty; - empty.applyToken = sp<IBinder>(); - mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags, - empty.applyToken, empty.inputWindowCommands, - empty.desiredPresentTime, empty.isAutoTimestamp, - empty.uncacheBuffers, mHasListenerCallbacks, mCallbacks, empty.id, - empty.mergedTransactionIds); + empty.mApplyToken = sp<IBinder>(); + empty.mHasListenerCallbacks = mHasListenerCallbacks; + empty.mListenerCallbacks = mCallbacks; + mFlinger.setTransactionState(std::move(empty)); // flush transaction queue should flush as desiredPresentTime has // passed @@ -406,9 +370,9 @@ public: const auto kFrameTimelineInfo = FrameTimelineInfo{}; setupSingle(transaction, kFlags, kDesiredPresentTime, kIsAutoTimestamp, kFrameTimelineInfo); - transaction.applyToken = applyToken; + transaction.mApplyToken = applyToken; for (const auto& state : states) { - transaction.states.push_back(state); + transaction.mComposerStates.push_back(state); } return transaction; @@ -420,7 +384,7 @@ public: EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size()); std::unordered_set<uint32_t> createdLayers; for (auto transaction : transactions) { - for (auto& state : transaction.states) { + for (auto& state : transaction.mComposerStates) { auto layerId = static_cast<uint32_t>(state.state.layerId); if (createdLayers.find(layerId) == createdLayers.end()) { mFlinger.addLayer(layerId); @@ -434,8 +398,8 @@ public: for (auto transaction : transactions) { std::vector<ResolvedComposerState> resolvedStates; - resolvedStates.reserve(transaction.states.size()); - for (auto& state : transaction.states) { + resolvedStates.reserve(transaction.mComposerStates.size()); + for (auto& state : transaction.mComposerStates) { ResolvedComposerState resolvedState; resolvedState.state = std::move(state.state); resolvedState.externalTexture = @@ -446,15 +410,9 @@ public: resolvedStates.emplace_back(resolvedState); } - QueuedTransactionState transactionState(transaction.frameTimelineInfo, resolvedStates, - transaction.displays, transaction.flags, - transaction.applyToken, - transaction.inputWindowCommands, - transaction.desiredPresentTime, - transaction.isAutoTimestamp, {}, systemTime(), - mHasListenerCallbacks, mCallbacks, getpid(), - static_cast<int>(getuid()), transaction.id, - transaction.mergedTransactionIds); + QueuedTransactionState transactionState(std::move(transaction), + std::move(resolvedStates), {}, systemTime(), + getpid(), static_cast<int>(getuid())); mFlinger.setTransactionStateInternal(transactionState); } mFlinger.flushTransactionQueues(); diff --git a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp index d3eec5c6f3..b36ad213c8 100644 --- a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp @@ -66,7 +66,7 @@ TEST(TransactionProtoParserTest, parse) { display.token = nullptr; } display.width = 85; - t1.displays.add(display); + t1.displays.push_back(display); } class TestMapper : public TransactionProtoParser::FlingerDataMapper { diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp index 918107d270..ccf6a9c7f6 100644 --- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp @@ -304,6 +304,53 @@ TEST_F(VSyncPredictorTest, againstOutliersDiscontinuous_500hzLowVariance) { EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError)); } +TEST_F(VSyncPredictorTest, recoverAfterDriftedVSyncAreReplacedWithCorrectVSync) { + SET_FLAG_FOR_TEST(flags::vsync_predictor_recovery, true); + auto constexpr idealPeriodNs = 4166666; + auto constexpr minFrameIntervalNs = 8333333; + auto constexpr idealPeriod = Fps::fromPeriodNsecs(idealPeriodNs); + auto constexpr minFrameRate = Fps::fromPeriodNsecs(minFrameIntervalNs); + hal::VrrConfig vrrConfig{.minFrameIntervalNs = minFrameIntervalNs}; + ftl::NonNull<DisplayModePtr> mode = + ftl::as_non_null(createVrrDisplayMode(DisplayModeId(0), idealPeriod, vrrConfig)); + VSyncPredictor vrrTracker{std::make_unique<ClockWrapper>(mClock), mode, kHistorySize, + kMinimumSamplesForPrediction, kOutlierTolerancePercent}; + vrrTracker.setRenderRate(minFrameRate, /*applyImmediately*/ true); + // Curated list of VSyncs that causes the VSync drift. + std::vector<nsecs_t> const simulatedVsyncs{74473665741, 74481774375, 74489911818, 74497993491, + 74506000833, 74510002150, 74513904390, 74517748707, + 74521550947, 74525383187, 74529165427, 74533067667, + 74536751484, 74540653724, 74544282649, 74548084889, + 74551917129, 74555699369, 74559601609, 74563601611, + 74567503851, 74571358168, 74575260408, 74578889333, + 74582691573, 74586523813, 74590306053, 74593589870, + 74597492110, 74601121035, 74604923275, 74608755515, + 74612537755, 74616166680, 74619795605, 74623424530, + 74627043455, 74630645695, 74634245935, 74637778175, + 74641291992, 74644794232, 74648275157, 74651575397, + 74654807637, 74658007877, 74661176117, 74664345357}; + for (auto const& timestamp : simulatedVsyncs) { + vrrTracker.addVsyncTimestamp(timestamp); + } + auto slope = vrrTracker.getVSyncPredictionModel().slope; + // Without using the idealPeriod for the calculation of the VSync predictor mode the + // the slope would be 3343031 + EXPECT_THAT(slope, IsCloseTo(4347805, mMaxRoundingError)); + EXPECT_FALSE(vrrTracker.needsMoreSamples()); + + auto lastVsync = 74664345357; + // Add valid VSyncs to replace the drifted VSyncs + for (int i = 0; i <= kHistorySize; i++) { + lastVsync += minFrameIntervalNs; + EXPECT_TRUE(vrrTracker.addVsyncTimestamp(lastVsync)); + } + EXPECT_FALSE(vrrTracker.needsMoreSamples()); + slope = vrrTracker.getVSyncPredictionModel().slope; + // Corrected slop is closer to the idealPeriod + // when valid vsync are inserted otherwise this would still be 3349673 + EXPECT_THAT(slope, IsCloseTo(idealPeriodNs, mMaxRoundingError)); +} + TEST_F(VSyncPredictorTest, handlesVsyncChange) { auto const fastPeriod = 100; auto const fastTimeBase = 100; @@ -402,11 +449,7 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { std::vector<nsecs_t> const simulatedVsyncs{ 158929578733000, 158929306806205, // oldest TS in ringbuffer - 158929650879052, - 158929661969209, - 158929684198847, - 158929695268171, - 158929706370359, + 158929650879052, 158929661969209, 158929684198847, 158929695268171, 158929706370359, }; auto const idealPeriod = 11111111; auto const expectedPeriod = 11113919; @@ -421,9 +464,9 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { EXPECT_THAT(slope, IsCloseTo(expectedPeriod, mMaxRoundingError)); EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError)); - // (timePoint - oldestTS) % expectedPeriod works out to be: 395334 - // (timePoint - oldestTS) / expectedPeriod works out to be: 38.96 - // so failure to account for the offset will floor the ordinal to 38, which was in the past. + // (timePoint - oldestTS) % expectedPeriod works out to be: 10702663 + // (timePoint - oldestTS) / expectedPeriod works out to be: 37.96 + // so failure to account for the offset will floor the ordinal to 37, which was in the past. auto const timePoint = 158929728723871; auto const prediction = tracker.nextAnticipatedVSyncTimeFrom(timePoint); EXPECT_THAT(prediction, Ge(timePoint)); diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h index 2bf66ac54e..7319f1ee22 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -193,6 +193,8 @@ public: MOCK_METHOD(Error, getLuts, (Display, const std::vector<sp<GraphicBuffer>>&, std::vector<aidl::android::hardware::graphics::composer3::Luts>*)); + MOCK_METHOD4(getLayerPresentFences, + Error(Display, std::vector<Layer>*, std::vector<int>*, std::vector<int64_t>*)); }; } // namespace Hwc2::mock diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h index 7bd85cd59f..01d078bbf1 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h @@ -44,7 +44,8 @@ public: MOCK_METHOD(bool, allocateVirtualDisplay, (HalVirtualDisplayId, ui::Size, ui::PixelFormat*), (override)); MOCK_METHOD(void, allocatePhysicalDisplay, - (hal::HWDisplayId, PhysicalDisplayId, std::optional<ui::Size>), (override)); + (hal::HWDisplayId, PhysicalDisplayId, uint8_t port, std::optional<ui::Size>), + (override)); MOCK_METHOD(std::shared_ptr<HWC2::Layer>, createLayer, (HalDisplayId), (override)); MOCK_METHOD(status_t, getDeviceCompositionChanges, @@ -81,7 +82,7 @@ public: (PhysicalDisplayId, float, float, const Hwc2::Composer::DisplayBrightnessOptions&), (override)); MOCK_METHOD(std::optional<DisplayIdentificationInfo>, onHotplug, - (hal::HWDisplayId, hal::Connection), (override)); + (hal::HWDisplayId, HWComposer::HotplugEvent), (override)); MOCK_METHOD(bool, updatesDeviceProductInfoOnHotplugReconnect, (), (const, override)); MOCK_METHOD(std::optional<PhysicalDisplayId>, onVsync, (hal::HWDisplayId, int64_t)); MOCK_METHOD(void, setVsyncEnabled, (PhysicalDisplayId, hal::Vsync), (override)); diff --git a/services/surfaceflinger/tests/unittests/mock/PowerAdvisor/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/PowerAdvisor/MockPowerAdvisor.h index fd55597d7a..5abee16bd0 100644 --- a/services/surfaceflinger/tests/unittests/mock/PowerAdvisor/MockPowerAdvisor.h +++ b/services/surfaceflinger/tests/unittests/mock/PowerAdvisor/MockPowerAdvisor.h @@ -65,6 +65,10 @@ public: MOCK_METHOD(void, setTotalFrameTargetWorkDuration, (Duration targetDuration), (override)); MOCK_METHOD(std::shared_ptr<SessionManager>, getSessionManager, (), (override)); MOCK_METHOD(sp<IBinder>, getOrCreateSessionManagerForBinder, (uid_t uid), (override)); + MOCK_METHOD(void, setQueuedWorkload, (ftl::Flags<Workload> workload), (override)); + MOCK_METHOD(void, setScreenshotWorkload, (), (override)); + MOCK_METHOD(void, setCommittedWorkload, (ftl::Flags<Workload> workload), (override)); + MOCK_METHOD(void, setCompositedWorkload, (ftl::Flags<Workload> workload), (override)); }; } // namespace android::adpf::mock diff --git a/services/surfaceflinger/tests/vsync/vsync.cpp b/services/surfaceflinger/tests/vsync/vsync.cpp index 8b4a6be1bf..77a68d9197 100644 --- a/services/surfaceflinger/tests/vsync/vsync.cpp +++ b/services/surfaceflinger/tests/vsync/vsync.cpp @@ -41,7 +41,7 @@ int receiver(int /*fd*/, int /*events*/, void* data) while ((n = q->getEvents(buffer, 1)) > 0) { for (int i=0 ; i<n ; i++) { - if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { + if (buffer[i].header.type == DisplayEventType::DISPLAY_EVENT_VSYNC) { printf("event vsync: count=%d\t", buffer[i].vsync.count); } if (oldTimeStamp) { diff --git a/services/vibratorservice/Android.bp b/services/vibratorservice/Android.bp index 4735ae5897..ed03cfc3f5 100644 --- a/services/vibratorservice/Android.bp +++ b/services/vibratorservice/Android.bp @@ -42,14 +42,9 @@ cc_library_shared { shared_libs: [ "libbinder_ndk", - "libhidlbase", "liblog", "libutils", "android.hardware.vibrator-V3-ndk", - "android.hardware.vibrator@1.0", - "android.hardware.vibrator@1.1", - "android.hardware.vibrator@1.2", - "android.hardware.vibrator@1.3", ], cflags: [ diff --git a/services/vibratorservice/VibratorHalController.cpp b/services/vibratorservice/VibratorHalController.cpp index 283a5f0301..302e3e1299 100644 --- a/services/vibratorservice/VibratorHalController.cpp +++ b/services/vibratorservice/VibratorHalController.cpp @@ -18,8 +18,6 @@ #include <aidl/android/hardware/vibrator/IVibrator.h> #include <android/binder_manager.h> -#include <android/hardware/vibrator/1.3/IVibrator.h> -#include <hardware/vibrator.h> #include <utils/Log.h> @@ -31,15 +29,10 @@ using aidl::android::hardware::vibrator::CompositeEffect; using aidl::android::hardware::vibrator::CompositePrimitive; using aidl::android::hardware::vibrator::Effect; using aidl::android::hardware::vibrator::EffectStrength; +using aidl::android::hardware::vibrator::IVibrator; using std::chrono::milliseconds; -namespace V1_0 = android::hardware::vibrator::V1_0; -namespace V1_1 = android::hardware::vibrator::V1_1; -namespace V1_2 = android::hardware::vibrator::V1_2; -namespace V1_3 = android::hardware::vibrator::V1_3; -namespace Aidl = aidl::android::hardware::vibrator; - namespace android { namespace vibrator { @@ -53,9 +46,9 @@ std::shared_ptr<HalWrapper> connectHal(std::shared_ptr<CallbackScheduler> schedu return nullptr; } - auto serviceName = std::string(Aidl::IVibrator::descriptor) + "/default"; + auto serviceName = std::string(IVibrator::descriptor) + "/default"; if (AServiceManager_isDeclared(serviceName.c_str())) { - std::shared_ptr<Aidl::IVibrator> hal = Aidl::IVibrator::fromBinder( + std::shared_ptr<IVibrator> hal = IVibrator::fromBinder( ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str()))); if (hal) { ALOGV("Successfully connected to Vibrator HAL AIDL service."); @@ -63,30 +56,9 @@ std::shared_ptr<HalWrapper> connectHal(std::shared_ptr<CallbackScheduler> schedu } } - sp<V1_0::IVibrator> halV1_0 = V1_0::IVibrator::getService(); - if (halV1_0 == nullptr) { - ALOGV("Vibrator HAL service not available."); - gHalExists = false; - return nullptr; - } - - sp<V1_3::IVibrator> halV1_3 = V1_3::IVibrator::castFrom(halV1_0); - if (halV1_3) { - ALOGV("Successfully connected to Vibrator HAL v1.3 service."); - return std::make_shared<HidlHalWrapperV1_3>(std::move(scheduler), halV1_3); - } - sp<V1_2::IVibrator> halV1_2 = V1_2::IVibrator::castFrom(halV1_0); - if (halV1_2) { - ALOGV("Successfully connected to Vibrator HAL v1.2 service."); - return std::make_shared<HidlHalWrapperV1_2>(std::move(scheduler), halV1_2); - } - sp<V1_1::IVibrator> halV1_1 = V1_1::IVibrator::castFrom(halV1_0); - if (halV1_1) { - ALOGV("Successfully connected to Vibrator HAL v1.1 service."); - return std::make_shared<HidlHalWrapperV1_1>(std::move(scheduler), halV1_1); - } - ALOGV("Successfully connected to Vibrator HAL v1.0 service."); - return std::make_shared<HidlHalWrapperV1_0>(std::move(scheduler), halV1_0); + ALOGV("Vibrator HAL service not available."); + gHalExists = false; + return nullptr; } // ------------------------------------------------------------------------------------------------- diff --git a/services/vibratorservice/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp index 3ddc4f2aca..5d4c17dc76 100644 --- a/services/vibratorservice/VibratorHalWrapper.cpp +++ b/services/vibratorservice/VibratorHalWrapper.cpp @@ -17,7 +17,6 @@ #define LOG_TAG "VibratorHalWrapper" #include <aidl/android/hardware/vibrator/IVibrator.h> -#include <android/hardware/vibrator/1.3/IVibrator.h> #include <hardware/vibrator.h> #include <cmath> @@ -33,32 +32,18 @@ using aidl::android::hardware::vibrator::CompositePwleV2; using aidl::android::hardware::vibrator::Effect; using aidl::android::hardware::vibrator::EffectStrength; using aidl::android::hardware::vibrator::FrequencyAccelerationMapEntry; +using aidl::android::hardware::vibrator::IVibrator; using aidl::android::hardware::vibrator::PrimitivePwle; using aidl::android::hardware::vibrator::VendorEffect; using std::chrono::milliseconds; -namespace V1_0 = android::hardware::vibrator::V1_0; -namespace V1_1 = android::hardware::vibrator::V1_1; -namespace V1_2 = android::hardware::vibrator::V1_2; -namespace V1_3 = android::hardware::vibrator::V1_3; -namespace Aidl = aidl::android::hardware::vibrator; - namespace android { namespace vibrator { // ------------------------------------------------------------------------------------------------- -template <class T> -bool isStaticCastValid(Effect effect) { - T castEffect = static_cast<T>(effect); - auto iter = hardware::hidl_enum_range<T>(); - return castEffect >= *iter.begin() && castEffect <= *std::prev(iter.end()); -} - -// ------------------------------------------------------------------------------------------------- - Info HalWrapper::getInfo() { getCapabilities(); getPrimitiveDurations(); @@ -131,9 +116,10 @@ HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&, return HalResult<void>::unsupported(); } -HalResult<void> HalWrapper::composePwleV2(const CompositePwleV2&, const std::function<void()>&) { +HalResult<milliseconds> HalWrapper::composePwleV2(const CompositePwleV2&, + const std::function<void()>&) { ALOGV("Skipped composePwleV2 because it's not available in Vibrator HAL"); - return HalResult<void>::unsupported(); + return HalResult<milliseconds>::unsupported(); } HalResult<Capabilities> HalWrapper::getCapabilities() { @@ -260,7 +246,7 @@ void AidlHalWrapper::tryReconnect() { if (!result.isOk()) { return; } - std::shared_ptr<Aidl::IVibrator> newHandle = result.value(); + std::shared_ptr<IVibrator> newHandle = result.value(); if (newHandle) { std::lock_guard<std::mutex> lock(mHandleMutex); mHandle = std::move(newHandle); @@ -359,11 +345,18 @@ HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwl return HalResultFactory::fromStatus(getHal()->composePwle(primitives, cb)); } -HalResult<void> AidlHalWrapper::composePwleV2(const CompositePwleV2& composite, - const std::function<void()>& completionCallback) { +HalResult<milliseconds> AidlHalWrapper::composePwleV2( + const CompositePwleV2& composite, const std::function<void()>& completionCallback) { // This method should always support callbacks, so no need to double check. auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback); - return HalResultFactory::fromStatus(getHal()->composePwleV2(composite, cb)); + + milliseconds totalDuration(0); + for (const auto& primitive : composite.pwlePrimitives) { + totalDuration += milliseconds(primitive.timeMillis); + } + + return HalResultFactory::fromStatus<milliseconds>(getHal()->composePwleV2(composite, cb), + totalDuration); } HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() { @@ -506,219 +499,13 @@ AidlHalWrapper::getFrequencyToOutputAccelerationMapInternal() { frequencyToOutputAccelerationMap); } -std::shared_ptr<Aidl::IVibrator> AidlHalWrapper::getHal() { +std::shared_ptr<IVibrator> AidlHalWrapper::getHal() { std::lock_guard<std::mutex> lock(mHandleMutex); return mHandle; } // ------------------------------------------------------------------------------------------------- -template <typename I> -HalResult<void> HidlHalWrapper<I>::ping() { - return HalResultFactory::fromReturn(getHal()->ping()); -} - -template <typename I> -void HidlHalWrapper<I>::tryReconnect() { - sp<I> newHandle = I::tryGetService(); - if (newHandle) { - std::lock_guard<std::mutex> lock(mHandleMutex); - mHandle = std::move(newHandle); - } -} - -template <typename I> -HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout, - const std::function<void()>& completionCallback) { - auto status = getHal()->on(timeout.count()); - auto ret = HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR)); - if (ret.isOk()) { - mCallbackScheduler->schedule(completionCallback, timeout); - } - return ret; -} - -template <typename I> -HalResult<void> HidlHalWrapper<I>::off() { - auto status = getHal()->off(); - return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR)); -} - -template <typename I> -HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) { - uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max()); - auto status = getHal()->setAmplitude(amp); - return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR)); -} - -template <typename I> -HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) { - ALOGV("Skipped setExternalControl because Vibrator HAL does not support it"); - return HalResult<void>::unsupported(); -} - -template <typename I> -HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) { - ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available"); - return HalResult<void>::unsupported(); -} - -template <typename I> -HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) { - ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available"); - return HalResult<void>::unsupported(); -} - -template <typename I> -HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() { - hardware::Return<bool> result = getHal()->supportsAmplitudeControl(); - Capabilities capabilities = - result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE; - return HalResultFactory::fromReturn<Capabilities>(std::move(result), capabilities); -} - -template <typename I> -template <typename T> -HalResult<milliseconds> HidlHalWrapper<I>::performInternal( - perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength, - const std::function<void()>& completionCallback) { - V1_0::Status status; - int32_t lengthMs; - auto effectCallback = [&status, &lengthMs](V1_0::Status retStatus, uint32_t retLengthMs) { - status = retStatus; - lengthMs = retLengthMs; - }; - - V1_0::EffectStrength effectStrength = static_cast<V1_0::EffectStrength>(strength); - auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback); - milliseconds length = milliseconds(lengthMs); - - auto ret = HalResultFactory::fromReturn<milliseconds>(std::move(result), status, length); - if (ret.isOk()) { - mCallbackScheduler->schedule(completionCallback, length); - } - - return ret; -} - -template <typename I> -sp<I> HidlHalWrapper<I>::getHal() { - std::lock_guard<std::mutex> lock(mHandleMutex); - return mHandle; -} - -// ------------------------------------------------------------------------------------------------- - -HalResult<milliseconds> HidlHalWrapperV1_0::performEffect( - Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) { - if (isStaticCastValid<V1_0::Effect>(effect)) { - return performInternal(&V1_0::IVibrator::perform, getHal(), - static_cast<V1_0::Effect>(effect), strength, completionCallback); - } - - ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s", - Aidl::toString(effect).c_str()); - return HalResult<milliseconds>::unsupported(); -} - -// ------------------------------------------------------------------------------------------------- - -HalResult<milliseconds> HidlHalWrapperV1_1::performEffect( - Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) { - if (isStaticCastValid<V1_0::Effect>(effect)) { - return performInternal(&V1_1::IVibrator::perform, getHal(), - static_cast<V1_0::Effect>(effect), strength, completionCallback); - } - if (isStaticCastValid<V1_1::Effect_1_1>(effect)) { - return performInternal(&V1_1::IVibrator::perform_1_1, getHal(), - static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback); - } - - ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s", - Aidl::toString(effect).c_str()); - return HalResult<milliseconds>::unsupported(); -} - -// ------------------------------------------------------------------------------------------------- - -HalResult<milliseconds> HidlHalWrapperV1_2::performEffect( - Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) { - if (isStaticCastValid<V1_0::Effect>(effect)) { - return performInternal(&V1_2::IVibrator::perform, getHal(), - static_cast<V1_0::Effect>(effect), strength, completionCallback); - } - if (isStaticCastValid<V1_1::Effect_1_1>(effect)) { - return performInternal(&V1_2::IVibrator::perform_1_1, getHal(), - static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback); - } - if (isStaticCastValid<V1_2::Effect>(effect)) { - return performInternal(&V1_2::IVibrator::perform_1_2, getHal(), - static_cast<V1_2::Effect>(effect), strength, completionCallback); - } - - ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s", - Aidl::toString(effect).c_str()); - return HalResult<milliseconds>::unsupported(); -} - -// ------------------------------------------------------------------------------------------------- - -HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) { - auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled)); - return HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR)); -} - -HalResult<milliseconds> HidlHalWrapperV1_3::performEffect( - Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) { - if (isStaticCastValid<V1_0::Effect>(effect)) { - return performInternal(&V1_3::IVibrator::perform, getHal(), - static_cast<V1_0::Effect>(effect), strength, completionCallback); - } - if (isStaticCastValid<V1_1::Effect_1_1>(effect)) { - return performInternal(&V1_3::IVibrator::perform_1_1, getHal(), - static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback); - } - if (isStaticCastValid<V1_2::Effect>(effect)) { - return performInternal(&V1_3::IVibrator::perform_1_2, getHal(), - static_cast<V1_2::Effect>(effect), strength, completionCallback); - } - if (isStaticCastValid<V1_3::Effect>(effect)) { - return performInternal(&V1_3::IVibrator::perform_1_3, getHal(), - static_cast<V1_3::Effect>(effect), strength, completionCallback); - } - - ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s", - Aidl::toString(effect).c_str()); - return HalResult<milliseconds>::unsupported(); -} - -HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() { - Capabilities capabilities = Capabilities::NONE; - - sp<V1_3::IVibrator> hal = getHal(); - auto amplitudeResult = hal->supportsAmplitudeControl(); - if (!amplitudeResult.isOk()) { - return HalResultFactory::fromReturn<Capabilities>(std::move(amplitudeResult), capabilities); - } - - auto externalControlResult = hal->supportsExternalControl(); - if (amplitudeResult.withDefault(false)) { - capabilities |= Capabilities::AMPLITUDE_CONTROL; - } - if (externalControlResult.withDefault(false)) { - capabilities |= Capabilities::EXTERNAL_CONTROL; - - if (amplitudeResult.withDefault(false)) { - capabilities |= Capabilities::EXTERNAL_AMPLITUDE_CONTROL; - } - } - - return HalResultFactory::fromReturn<Capabilities>(std::move(externalControlResult), - capabilities); -} - -// ------------------------------------------------------------------------------------------------- - }; // namespace vibrator }; // namespace android diff --git a/services/vibratorservice/VibratorManagerHalController.cpp b/services/vibratorservice/VibratorManagerHalController.cpp index 494f88f10e..31b6ed030f 100644 --- a/services/vibratorservice/VibratorManagerHalController.cpp +++ b/services/vibratorservice/VibratorManagerHalController.cpp @@ -20,7 +20,10 @@ #include <vibratorservice/VibratorManagerHalController.h> -namespace Aidl = aidl::android::hardware::vibrator; +using aidl::android::hardware::vibrator::IVibrationSession; +using aidl::android::hardware::vibrator::IVibrator; +using aidl::android::hardware::vibrator::IVibratorManager; +using aidl::android::hardware::vibrator::VibrationSessionConfig; namespace android { @@ -29,9 +32,9 @@ namespace vibrator { std::shared_ptr<ManagerHalWrapper> connectManagerHal(std::shared_ptr<CallbackScheduler> scheduler) { static bool gHalExists = true; if (gHalExists) { - auto serviceName = std::string(Aidl::IVibratorManager::descriptor) + "/default"; + auto serviceName = std::string(IVibratorManager::descriptor) + "/default"; if (AServiceManager_isDeclared(serviceName.c_str())) { - std::shared_ptr<Aidl::IVibratorManager> hal = Aidl::IVibratorManager::fromBinder( + std::shared_ptr<IVibratorManager> hal = IVibratorManager::fromBinder( ndk::SpAIBinder(AServiceManager_checkService(serviceName.c_str()))); if (hal) { ALOGV("Successfully connected to VibratorManager HAL AIDL service."); @@ -41,6 +44,7 @@ std::shared_ptr<ManagerHalWrapper> connectManagerHal(std::shared_ptr<CallbackSch } } + ALOGV("VibratorManager HAL service not available."); gHalExists = false; return std::make_shared<LegacyManagerHalWrapper>(); } @@ -150,10 +154,10 @@ HalResult<void> ManagerHalController::cancelSynced() { return apply(cancelSyncedFn, "cancelSynced"); } -HalResult<std::shared_ptr<Aidl::IVibrationSession>> ManagerHalController::startSession( - const std::vector<int32_t>& ids, const Aidl::VibrationSessionConfig& config, +HalResult<std::shared_ptr<IVibrationSession>> ManagerHalController::startSession( + const std::vector<int32_t>& ids, const VibrationSessionConfig& config, const std::function<void()>& completionCallback) { - hal_fn<std::shared_ptr<Aidl::IVibrationSession>> startSessionFn = + hal_fn<std::shared_ptr<IVibrationSession>> startSessionFn = [&](std::shared_ptr<ManagerHalWrapper> hal) { return hal->startSession(ids, config, completionCallback); }; diff --git a/services/vibratorservice/VibratorManagerHalWrapper.cpp b/services/vibratorservice/VibratorManagerHalWrapper.cpp index 3db8ff8699..bab3f58754 100644 --- a/services/vibratorservice/VibratorManagerHalWrapper.cpp +++ b/services/vibratorservice/VibratorManagerHalWrapper.cpp @@ -20,7 +20,10 @@ #include <vibratorservice/VibratorManagerHalWrapper.h> -namespace Aidl = aidl::android::hardware::vibrator; +using aidl::android::hardware::vibrator::IVibrationSession; +using aidl::android::hardware::vibrator::IVibrator; +using aidl::android::hardware::vibrator::IVibratorManager; +using aidl::android::hardware::vibrator::VibrationSessionConfig; namespace android { @@ -41,10 +44,9 @@ HalResult<void> ManagerHalWrapper::cancelSynced() { return HalResult<void>::unsupported(); } -HalResult<std::shared_ptr<Aidl::IVibrationSession>> ManagerHalWrapper::startSession( - const std::vector<int32_t>&, const Aidl::VibrationSessionConfig&, - const std::function<void()>&) { - return HalResult<std::shared_ptr<Aidl::IVibrationSession>>::unsupported(); +HalResult<std::shared_ptr<IVibrationSession>> ManagerHalWrapper::startSession( + const std::vector<int32_t>&, const VibrationSessionConfig&, const std::function<void()>&) { + return HalResult<std::shared_ptr<IVibrationSession>>::unsupported(); } HalResult<void> ManagerHalWrapper::clearSessions() { @@ -87,11 +89,11 @@ HalResult<std::shared_ptr<HalController>> LegacyManagerHalWrapper::getVibrator(i std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator( int32_t vibratorId, std::shared_ptr<CallbackScheduler> callbackScheduler) { - std::function<HalResult<std::shared_ptr<Aidl::IVibrator>>()> reconnectFn = [=, this]() { - std::shared_ptr<Aidl::IVibrator> vibrator; + std::function<HalResult<std::shared_ptr<IVibrator>>()> reconnectFn = [=, this]() { + std::shared_ptr<IVibrator> vibrator; auto status = this->getHal()->getVibrator(vibratorId, &vibrator); - return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrator>>(std::move(status), - vibrator); + return HalResultFactory::fromStatus<std::shared_ptr<IVibrator>>(std::move(status), + vibrator); }; auto result = reconnectFn(); if (!result.isOk()) { @@ -110,8 +112,8 @@ HalResult<void> AidlManagerHalWrapper::ping() { } void AidlManagerHalWrapper::tryReconnect() { - auto aidlServiceName = std::string(Aidl::IVibratorManager::descriptor) + "/default"; - std::shared_ptr<Aidl::IVibratorManager> newHandle = Aidl::IVibratorManager::fromBinder( + auto aidlServiceName = std::string(IVibratorManager::descriptor) + "/default"; + std::shared_ptr<IVibratorManager> newHandle = IVibratorManager::fromBinder( ndk::SpAIBinder(AServiceManager_checkService(aidlServiceName.c_str()))); if (newHandle) { std::lock_guard<std::mutex> lock(mHandleMutex); @@ -198,15 +200,14 @@ HalResult<void> AidlManagerHalWrapper::triggerSynced( return HalResultFactory::fromStatus(getHal()->triggerSynced(cb)); } -HalResult<std::shared_ptr<Aidl::IVibrationSession>> AidlManagerHalWrapper::startSession( - const std::vector<int32_t>& ids, const Aidl::VibrationSessionConfig& config, +HalResult<std::shared_ptr<IVibrationSession>> AidlManagerHalWrapper::startSession( + const std::vector<int32_t>& ids, const VibrationSessionConfig& config, const std::function<void()>& completionCallback) { auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback); - std::shared_ptr<Aidl::IVibrationSession> session; + std::shared_ptr<IVibrationSession> session; auto status = getHal()->startSession(ids, config, cb, &session); - return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrationSession>>(std::move(status), - std::move( - session)); + return HalResultFactory::fromStatus<std::shared_ptr<IVibrationSession>>(std::move(status), + std::move(session)); } HalResult<void> AidlManagerHalWrapper::cancelSynced() { @@ -227,7 +228,7 @@ HalResult<void> AidlManagerHalWrapper::clearSessions() { return HalResultFactory::fromStatus(getHal()->clearSessions()); } -std::shared_ptr<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() { +std::shared_ptr<IVibratorManager> AidlManagerHalWrapper::getHal() { std::lock_guard<std::mutex> lock(mHandleMutex); return mHandle; } diff --git a/services/vibratorservice/benchmarks/Android.bp b/services/vibratorservice/benchmarks/Android.bp index 915d6c7bc3..6fc5cf3517 100644 --- a/services/vibratorservice/benchmarks/Android.bp +++ b/services/vibratorservice/benchmarks/Android.bp @@ -29,15 +29,10 @@ cc_benchmark { ], shared_libs: [ "libbinder_ndk", - "libhidlbase", "liblog", "libutils", "libvibratorservice", "android.hardware.vibrator-V3-ndk", - "android.hardware.vibrator@1.0", - "android.hardware.vibrator@1.1", - "android.hardware.vibrator@1.2", - "android.hardware.vibrator@1.3", ], cflags: [ "-Wall", diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h index 339a6e1d0d..065227861d 100644 --- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h @@ -22,7 +22,6 @@ #include <android-base/thread_annotations.h> #include <android/binder_manager.h> -#include <android/hardware/vibrator/1.3/IVibrator.h> #include <binder/IServiceManager.h> #include <vibratorservice/VibratorCallbackScheduler.h> @@ -105,26 +104,6 @@ public: : fromFailedStatus<T>(std::move(status)); } - template <typename T> - static HalResult<T> fromStatus(hardware::vibrator::V1_0::Status&& status, T data) { - return (status == hardware::vibrator::V1_0::Status::OK) - ? HalResult<T>::ok(std::move(data)) - : fromFailedStatus<T>(std::move(status)); - } - - template <typename T, typename R> - static HalResult<T> fromReturn(hardware::Return<R>&& ret, T data) { - return ret.isOk() ? HalResult<T>::ok(std::move(data)) - : fromFailedReturn<T, R>(std::move(ret)); - } - - template <typename T, typename R> - static HalResult<T> fromReturn(hardware::Return<R>&& ret, - hardware::vibrator::V1_0::Status status, T data) { - return ret.isOk() ? fromStatus<T>(std::move(status), std::move(data)) - : fromFailedReturn<T, R>(std::move(ret)); - } - static HalResult<void> fromStatus(status_t status) { return (status == android::OK) ? HalResult<void>::ok() : fromFailedStatus<void>(std::move(status)); @@ -134,17 +113,6 @@ public: return status.isOk() ? HalResult<void>::ok() : fromFailedStatus<void>(std::move(status)); } - static HalResult<void> fromStatus(hardware::vibrator::V1_0::Status&& status) { - return (status == hardware::vibrator::V1_0::Status::OK) - ? HalResult<void>::ok() - : fromFailedStatus<void>(std::move(status)); - } - - template <typename R> - static HalResult<void> fromReturn(hardware::Return<R>&& ret) { - return ret.isOk() ? HalResult<void>::ok() : fromFailedReturn<void, R>(std::move(ret)); - } - private: template <typename T> static HalResult<T> fromFailedStatus(status_t status) { @@ -166,23 +134,6 @@ private: } return HalResult<T>::failed(status.getMessage()); } - - template <typename T> - static HalResult<T> fromFailedStatus(hardware::vibrator::V1_0::Status&& status) { - switch (status) { - case hardware::vibrator::V1_0::Status::UNSUPPORTED_OPERATION: - return HalResult<T>::unsupported(); - default: - auto msg = "android::hardware::vibrator::V1_0::Status = " + toString(status); - return HalResult<T>::failed(msg.c_str()); - } - } - - template <typename T, typename R> - static HalResult<T> fromFailedReturn(hardware::Return<R>&& ret) { - return ret.isDeadObject() ? HalResult<T>::transactionFailed(ret.description().c_str()) - : HalResult<T>::failed(ret.description().c_str()); - } }; // ------------------------------------------------------------------------------------------------- @@ -423,8 +374,8 @@ public: virtual HalResult<void> performPwleEffect(const std::vector<PrimitivePwle>& primitives, const std::function<void()>& completionCallback); - virtual HalResult<void> composePwleV2(const CompositePwleV2& composite, - const std::function<void()>& completionCallback); + virtual HalResult<std::chrono::milliseconds> composePwleV2( + const CompositePwleV2& composite, const std::function<void()>& completionCallback); protected: // Shared pointer to allow CallbackScheduler to outlive this wrapper. @@ -511,8 +462,9 @@ public: const std::vector<PrimitivePwle>& primitives, const std::function<void()>& completionCallback) override final; - HalResult<void> composePwleV2(const CompositePwleV2& composite, - const std::function<void()>& completionCallback) override final; + HalResult<std::chrono::milliseconds> composePwleV2( + const CompositePwleV2& composite, + const std::function<void()>& completionCallback) override final; protected: HalResult<Capabilities> getCapabilitiesInternal() override final; @@ -547,108 +499,6 @@ private: std::shared_ptr<IVibrator> getHal(); }; -// Wrapper for the HDIL Vibrator HALs. -template <typename I> -class HidlHalWrapper : public HalWrapper { -public: - HidlHalWrapper(std::shared_ptr<CallbackScheduler> scheduler, sp<I> handle) - : HalWrapper(std::move(scheduler)), mHandle(std::move(handle)) {} - virtual ~HidlHalWrapper() = default; - - HalResult<void> ping() override final; - void tryReconnect() override final; - - HalResult<void> on(std::chrono::milliseconds timeout, - const std::function<void()>& completionCallback) override final; - HalResult<void> off() override final; - - HalResult<void> setAmplitude(float amplitude) override final; - virtual HalResult<void> setExternalControl(bool enabled) override; - - HalResult<void> alwaysOnEnable(int32_t id, HalWrapper::Effect effect, - HalWrapper::EffectStrength strength) override final; - HalResult<void> alwaysOnDisable(int32_t id) override final; - -protected: - std::mutex mHandleMutex; - sp<I> mHandle GUARDED_BY(mHandleMutex); - - virtual HalResult<Capabilities> getCapabilitiesInternal() override; - - template <class T> - using perform_fn = - hardware::Return<void> (I::*)(T, hardware::vibrator::V1_0::EffectStrength, - hardware::vibrator::V1_0::IVibrator::perform_cb); - - template <class T> - HalResult<std::chrono::milliseconds> performInternal( - perform_fn<T> performFn, sp<I> handle, T effect, HalWrapper::EffectStrength strength, - const std::function<void()>& completionCallback); - - sp<I> getHal(); -}; - -// Wrapper for the HDIL Vibrator HAL v1.0. -class HidlHalWrapperV1_0 : public HidlHalWrapper<hardware::vibrator::V1_0::IVibrator> { -public: - HidlHalWrapperV1_0(std::shared_ptr<CallbackScheduler> scheduler, - sp<hardware::vibrator::V1_0::IVibrator> handle) - : HidlHalWrapper<hardware::vibrator::V1_0::IVibrator>(std::move(scheduler), - std::move(handle)) {} - virtual ~HidlHalWrapperV1_0() = default; - - HalResult<std::chrono::milliseconds> performEffect( - HalWrapper::Effect effect, HalWrapper::EffectStrength strength, - const std::function<void()>& completionCallback) override final; -}; - -// Wrapper for the HDIL Vibrator HAL v1.1. -class HidlHalWrapperV1_1 : public HidlHalWrapper<hardware::vibrator::V1_1::IVibrator> { -public: - HidlHalWrapperV1_1(std::shared_ptr<CallbackScheduler> scheduler, - sp<hardware::vibrator::V1_1::IVibrator> handle) - : HidlHalWrapper<hardware::vibrator::V1_1::IVibrator>(std::move(scheduler), - std::move(handle)) {} - virtual ~HidlHalWrapperV1_1() = default; - - HalResult<std::chrono::milliseconds> performEffect( - HalWrapper::Effect effect, HalWrapper::EffectStrength strength, - const std::function<void()>& completionCallback) override final; -}; - -// Wrapper for the HDIL Vibrator HAL v1.2. -class HidlHalWrapperV1_2 : public HidlHalWrapper<hardware::vibrator::V1_2::IVibrator> { -public: - HidlHalWrapperV1_2(std::shared_ptr<CallbackScheduler> scheduler, - sp<hardware::vibrator::V1_2::IVibrator> handle) - : HidlHalWrapper<hardware::vibrator::V1_2::IVibrator>(std::move(scheduler), - std::move(handle)) {} - virtual ~HidlHalWrapperV1_2() = default; - - HalResult<std::chrono::milliseconds> performEffect( - HalWrapper::Effect effect, HalWrapper::EffectStrength strength, - const std::function<void()>& completionCallback) override final; -}; - -// Wrapper for the HDIL Vibrator HAL v1.3. -class HidlHalWrapperV1_3 : public HidlHalWrapper<hardware::vibrator::V1_3::IVibrator> { -public: - HidlHalWrapperV1_3(std::shared_ptr<CallbackScheduler> scheduler, - sp<hardware::vibrator::V1_3::IVibrator> handle) - : HidlHalWrapper<hardware::vibrator::V1_3::IVibrator>(std::move(scheduler), - std::move(handle)) {} - virtual ~HidlHalWrapperV1_3() = default; - - HalResult<void> setExternalControl(bool enabled) override final; - - HalResult<std::chrono::milliseconds> performEffect( - HalWrapper::Effect effect, HalWrapper::EffectStrength strength, - const std::function<void()>& completionCallback) override final; - -protected: - HalResult<Capabilities> getCapabilitiesInternal() override final; -}; - // ------------------------------------------------------------------------------------------------- }; // namespace vibrator diff --git a/services/vibratorservice/test/Android.bp b/services/vibratorservice/test/Android.bp index 92527eb5cf..038248e636 100644 --- a/services/vibratorservice/test/Android.bp +++ b/services/vibratorservice/test/Android.bp @@ -29,10 +29,6 @@ cc_test { "VibratorCallbackSchedulerTest.cpp", "VibratorHalControllerTest.cpp", "VibratorHalWrapperAidlTest.cpp", - "VibratorHalWrapperHidlV1_0Test.cpp", - "VibratorHalWrapperHidlV1_1Test.cpp", - "VibratorHalWrapperHidlV1_2Test.cpp", - "VibratorHalWrapperHidlV1_3Test.cpp", "VibratorManagerHalControllerTest.cpp", "VibratorManagerHalWrapperAidlTest.cpp", "VibratorManagerHalWrapperLegacyTest.cpp", @@ -45,15 +41,10 @@ cc_test { shared_libs: [ "libbase", "libbinder_ndk", - "libhidlbase", "liblog", "libvibratorservice", "libutils", "android.hardware.vibrator-V3-ndk", - "android.hardware.vibrator@1.0", - "android.hardware.vibrator@1.1", - "android.hardware.vibrator@1.2", - "android.hardware.vibrator@1.3", ], static_libs: [ "libgmock", diff --git a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp index c58e05cedb..7545148ee1 100644 --- a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp +++ b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp @@ -787,5 +787,6 @@ TEST_F(VibratorHalWrapperAidlTest, TestComposePwleV2) { result = mWrapper->composePwleV2(composite, callback); ASSERT_TRUE(result.isOk()); + ASSERT_EQ(300ms, result.value()); ASSERT_EQ(1, *callbackCounter.get()); } diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp deleted file mode 100644 index 04dbe4eb26..0000000000 --- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "VibratorHalWrapperHidlV1_0Test" - -#include <aidl/android/hardware/vibrator/IVibrator.h> -#include <android/persistable_bundle_aidl.h> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include <utils/Log.h> -#include <thread> - -#include <vibratorservice/VibratorCallbackScheduler.h> -#include <vibratorservice/VibratorHalWrapper.h> - -#include "test_mocks.h" -#include "test_utils.h" - -namespace V1_0 = android::hardware::vibrator::V1_0; - -using aidl::android::hardware::vibrator::Braking; -using aidl::android::hardware::vibrator::CompositeEffect; -using aidl::android::hardware::vibrator::CompositePrimitive; -using aidl::android::hardware::vibrator::CompositePwleV2; -using aidl::android::hardware::vibrator::Effect; -using aidl::android::hardware::vibrator::EffectStrength; -using aidl::android::hardware::vibrator::IVibrator; -using aidl::android::hardware::vibrator::PrimitivePwle; -using aidl::android::hardware::vibrator::PwleV2Primitive; -using aidl::android::hardware::vibrator::VendorEffect; -using aidl::android::os::PersistableBundle; - -using namespace android; -using namespace std::chrono_literals; -using namespace testing; - -// ------------------------------------------------------------------------------------------------- - -class MockIVibratorV1_0 : public V1_0::IVibrator { -public: - MOCK_METHOD(hardware::Return<void>, ping, (), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, on, (uint32_t timeoutMs), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, off, (), (override)); - MOCK_METHOD(hardware::Return<bool>, supportsAmplitudeControl, (), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, setAmplitude, (uint8_t amplitude), (override)); - MOCK_METHOD(hardware::Return<void>, perform, - (V1_0::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override)); -}; - -// ------------------------------------------------------------------------------------------------- - -class VibratorHalWrapperHidlV1_0Test : public Test { -public: - void SetUp() override { - mMockHal = new StrictMock<MockIVibratorV1_0>(); - mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>(); - mWrapper = std::make_unique<vibrator::HidlHalWrapperV1_0>(mMockScheduler, mMockHal); - ASSERT_NE(mWrapper, nullptr); - } - -protected: - std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr; - std::unique_ptr<vibrator::HalWrapper> mWrapper = nullptr; - sp<StrictMock<MockIVibratorV1_0>> mMockHal = nullptr; -}; - -// ------------------------------------------------------------------------------------------------- - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestPing) { - EXPECT_CALL(*mMockHal.get(), ping()) - .Times(Exactly(2)) - .WillOnce([]() { return hardware::Return<void>(); }) - .WillRepeatedly([]() { - return hardware::Return<void>(hardware::Status::fromExceptionCode(-1)); - }); - - ASSERT_TRUE(mWrapper->ping().isOk()); - ASSERT_TRUE(mWrapper->ping().isFailed()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestOn) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), on(Eq(static_cast<uint32_t>(1)))) - .Times(Exactly(1)) - .WillRepeatedly( - [](uint32_t) { return hardware::Return<V1_0::Status>(V1_0::Status::OK); }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(1ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - EXPECT_CALL(*mMockHal.get(), on(Eq(static_cast<uint32_t>(10)))) - .Times(Exactly(1)) - .WillRepeatedly([](uint32_t) { - return hardware::Return<V1_0::Status>(V1_0::Status::UNSUPPORTED_OPERATION); - }); - EXPECT_CALL(*mMockHal.get(), on(Eq(static_cast<uint32_t>(11)))) - .Times(Exactly(1)) - .WillRepeatedly([](uint32_t) { - return hardware::Return<V1_0::Status>(V1_0::Status::BAD_VALUE); - }); - EXPECT_CALL(*mMockHal.get(), on(Eq(static_cast<uint32_t>(12)))) - .Times(Exactly(1)) - .WillRepeatedly([](uint32_t) { - return hardware::Return<V1_0::Status>(hardware::Status::fromExceptionCode(-1)); - }); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - - ASSERT_TRUE(mWrapper->on(1ms, callback).isOk()); - ASSERT_EQ(1, *callbackCounter.get()); - - ASSERT_TRUE(mWrapper->on(10ms, callback).isUnsupported()); - ASSERT_TRUE(mWrapper->on(11ms, callback).isFailed()); - ASSERT_TRUE(mWrapper->on(12ms, callback).isFailed()); - - // Callback not triggered for unsupported and on failure - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestOff) { - EXPECT_CALL(*mMockHal.get(), off()) - .Times(Exactly(4)) - .WillOnce([]() { return hardware::Return<V1_0::Status>(V1_0::Status::OK); }) - .WillOnce([]() { - return hardware::Return<V1_0::Status>(V1_0::Status::UNSUPPORTED_OPERATION); - }) - .WillOnce([]() { return hardware::Return<V1_0::Status>(V1_0::Status::BAD_VALUE); }) - .WillRepeatedly([]() { - return hardware::Return<V1_0::Status>(hardware::Status::fromExceptionCode(-1)); - }); - - ASSERT_TRUE(mWrapper->off().isOk()); - ASSERT_TRUE(mWrapper->off().isUnsupported()); - ASSERT_TRUE(mWrapper->off().isFailed()); - ASSERT_TRUE(mWrapper->off().isFailed()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestSetAmplitude) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(static_cast<uint8_t>(1)))) - .Times(Exactly(1)) - .WillRepeatedly( - [](uint8_t) { return hardware::Return<V1_0::Status>(V1_0::Status::OK); }); - EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(static_cast<uint8_t>(2)))) - .Times(Exactly(1)) - .WillRepeatedly([](uint8_t) { - return hardware::Return<V1_0::Status>(V1_0::Status::UNSUPPORTED_OPERATION); - }); - EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(static_cast<uint8_t>(3)))) - .Times(Exactly(1)) - .WillRepeatedly([](uint8_t) { - return hardware::Return<V1_0::Status>(V1_0::Status::BAD_VALUE); - }); - EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(static_cast<uint8_t>(4)))) - .Times(Exactly(1)) - .WillRepeatedly([](uint8_t) { - return hardware::Return<V1_0::Status>(hardware::Status::fromExceptionCode(-1)); - }); - } - - auto maxAmplitude = std::numeric_limits<uint8_t>::max(); - ASSERT_TRUE(mWrapper->setAmplitude(1.0f / maxAmplitude).isOk()); - ASSERT_TRUE(mWrapper->setAmplitude(2.0f / maxAmplitude).isUnsupported()); - ASSERT_TRUE(mWrapper->setAmplitude(3.0f / maxAmplitude).isFailed()); - ASSERT_TRUE(mWrapper->setAmplitude(4.0f / maxAmplitude).isFailed()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestSetExternalControlUnsupported) { - ASSERT_TRUE(mWrapper->setExternalControl(true).isUnsupported()); - ASSERT_TRUE(mWrapper->setExternalControl(false).isUnsupported()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestAlwaysOnEnableUnsupported) { - ASSERT_TRUE(mWrapper->alwaysOnEnable(1, Effect::CLICK, EffectStrength::LIGHT).isUnsupported()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestAlwaysOnDisableUnsupported) { - ASSERT_TRUE(mWrapper->alwaysOnDisable(1).isUnsupported()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoDoesNotCacheFailedResult) { - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()) - .Times(Exactly(2)) - .WillOnce([]() { - return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1)); - }) - .WillRepeatedly([]() { return hardware::Return<bool>(true); }); - - ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed()); - - vibrator::Info info = mWrapper->getInfo(); - ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, info.capabilities.value()); - ASSERT_TRUE(info.supportedEffects.isUnsupported()); - ASSERT_TRUE(info.supportedBraking.isUnsupported()); - ASSERT_TRUE(info.supportedPrimitives.isUnsupported()); - ASSERT_TRUE(info.primitiveDurations.isUnsupported()); - ASSERT_TRUE(info.primitiveDelayMax.isUnsupported()); - ASSERT_TRUE(info.pwlePrimitiveDurationMax.isUnsupported()); - ASSERT_TRUE(info.compositionSizeMax.isUnsupported()); - ASSERT_TRUE(info.pwleSizeMax.isUnsupported()); - ASSERT_TRUE(info.minFrequency.isUnsupported()); - ASSERT_TRUE(info.resonantFrequency.isUnsupported()); - ASSERT_TRUE(info.frequencyResolution.isUnsupported()); - ASSERT_TRUE(info.qFactor.isUnsupported()); - ASSERT_TRUE(info.maxAmplitudes.isUnsupported()); - ASSERT_TRUE(info.maxEnvelopeEffectSize.isUnsupported()); - ASSERT_TRUE(info.minEnvelopeEffectControlPointDuration.isUnsupported()); - ASSERT_TRUE(info.maxEnvelopeEffectControlPointDuration.isUnsupported()); - ASSERT_TRUE(info.frequencyToOutputAccelerationMap.isUnsupported()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoWithoutAmplitudeControl) { - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()).Times(Exactly(1)).WillRepeatedly([]() { - return hardware::Return<bool>(false); - }); - - ASSERT_EQ(vibrator::Capabilities::NONE, mWrapper->getInfo().capabilities.value()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoCachesResult) { - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()).Times(Exactly(1)).WillRepeatedly([]() { - return hardware::Return<bool>(true); - }); - - std::vector<std::thread> threads; - for (int i = 0; i < 10; i++) { - threads.push_back( - std::thread([&]() { ASSERT_TRUE(mWrapper->getInfo().capabilities.isOk()); })); - } - std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); }); - - vibrator::Info info = mWrapper->getInfo(); - ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, info.capabilities.value()); - ASSERT_TRUE(info.supportedEffects.isUnsupported()); - ASSERT_TRUE(info.supportedBraking.isUnsupported()); - ASSERT_TRUE(info.supportedPrimitives.isUnsupported()); - ASSERT_TRUE(info.primitiveDurations.isUnsupported()); - ASSERT_TRUE(info.minFrequency.isUnsupported()); - ASSERT_TRUE(info.resonantFrequency.isUnsupported()); - ASSERT_TRUE(info.frequencyResolution.isUnsupported()); - ASSERT_TRUE(info.qFactor.isUnsupported()); - ASSERT_TRUE(info.maxAmplitudes.isUnsupported()); - ASSERT_TRUE(info.maxEnvelopeEffectSize.isUnsupported()); - ASSERT_TRUE(info.minEnvelopeEffectControlPointDuration.isUnsupported()); - ASSERT_TRUE(info.maxEnvelopeEffectControlPointDuration.isUnsupported()); - ASSERT_TRUE(info.frequencyToOutputAccelerationMap.isUnsupported()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformEffect) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_0::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - EXPECT_CALL(*mMockHal.get(), - perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::MEDIUM), _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_0::perform_cb cb) { - cb(V1_0::Status::UNSUPPORTED_OPERATION, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockHal.get(), - perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::STRONG), _)) - .Times(Exactly(2)) - .WillOnce([](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_0::perform_cb cb) { - cb(V1_0::Status::BAD_VALUE, 10); - return hardware::Return<void>(); - }) - .WillRepeatedly( - [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_0::perform_cb) { - return hardware::Return<void>(hardware::Status::fromExceptionCode(-1)); - }); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - - auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback); - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); - - result = mWrapper->performEffect(Effect::CLICK, EffectStrength::MEDIUM, callback); - ASSERT_TRUE(result.isUnsupported()); - - result = mWrapper->performEffect(Effect::CLICK, EffectStrength::STRONG, callback); - ASSERT_TRUE(result.isFailed()); - - result = mWrapper->performEffect(Effect::CLICK, EffectStrength::STRONG, callback); - ASSERT_TRUE(result.isFailed()); - - // Callback not triggered for unsupported and on failure - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformEffectUnsupported) { - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - // Using TICK that is only available in v1.1 - auto result = mWrapper->performEffect(Effect::TICK, EffectStrength::LIGHT, callback); - ASSERT_TRUE(result.isUnsupported()); - // No callback is triggered. - ASSERT_EQ(0, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformVendorEffectUnsupported) { - PersistableBundle vendorData; // empty - VendorEffect vendorEffect; - vendorEffect.vendorData = vendorData; - vendorEffect.strength = EffectStrength::LIGHT; - vendorEffect.scale = 1.0f; - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - - ASSERT_TRUE(mWrapper->performVendorEffect(vendorEffect, callback).isUnsupported()); - - // No callback is triggered. - ASSERT_EQ(0, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformComposedEffectUnsupported) { - std::vector<CompositeEffect> emptyEffects, singleEffect, multipleEffects; - singleEffect.push_back( - vibrator::TestFactory::createCompositeEffect(CompositePrimitive::CLICK, 10ms, 0.0f)); - multipleEffects.push_back( - vibrator::TestFactory::createCompositeEffect(CompositePrimitive::SPIN, 100ms, 0.5f)); - multipleEffects.push_back( - vibrator::TestFactory::createCompositeEffect(CompositePrimitive::THUD, 1000ms, 1.0f)); - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - - ASSERT_TRUE(mWrapper->performComposedEffect(singleEffect, callback).isUnsupported()); - ASSERT_TRUE(mWrapper->performComposedEffect(multipleEffects, callback).isUnsupported()); - - // No callback is triggered. - ASSERT_EQ(0, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformPwleEffectUnsupported) { - std::vector<PrimitivePwle> emptyPrimitives, multiplePrimitives; - multiplePrimitives.push_back(vibrator::TestFactory::createActivePwle(0, 1, 0, 1, 10ms)); - multiplePrimitives.push_back(vibrator::TestFactory::createBrakingPwle(Braking::NONE, 100ms)); - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - - ASSERT_TRUE(mWrapper->performPwleEffect(emptyPrimitives, callback).isUnsupported()); - ASSERT_TRUE(mWrapper->performPwleEffect(multiplePrimitives, callback).isUnsupported()); - - // No callback is triggered. - ASSERT_EQ(0, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_0Test, TestComposePwleV2Unsupported) { - CompositePwleV2 composite; - composite.pwlePrimitives = { - PwleV2Primitive(/*amplitude=*/0.2, /*frequency=*/50, /*time=*/100), - PwleV2Primitive(/*amplitude=*/0.5, /*frequency=*/150, /*time=*/100), - PwleV2Primitive(/*amplitude=*/0.8, /*frequency=*/250, /*time=*/100), - }; - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - - ASSERT_TRUE(mWrapper->composePwleV2(composite, callback).isUnsupported()); - - // No callback is triggered. - ASSERT_EQ(0, *callbackCounter.get()); -} diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_1Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_1Test.cpp deleted file mode 100644 index b0a653769e..0000000000 --- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_1Test.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "VibratorHalWrapperHidlV1_1Test" - -#include <aidl/android/hardware/vibrator/IVibrator.h> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include <utils/Log.h> - -#include <vibratorservice/VibratorCallbackScheduler.h> -#include <vibratorservice/VibratorHalWrapper.h> - -#include "test_mocks.h" -#include "test_utils.h" - -namespace V1_0 = android::hardware::vibrator::V1_0; -namespace V1_1 = android::hardware::vibrator::V1_1; - -using aidl::android::hardware::vibrator::Effect; -using aidl::android::hardware::vibrator::EffectStrength; - -using namespace android; -using namespace std::chrono_literals; -using namespace testing; - -// ------------------------------------------------------------------------------------------------- - -class MockIVibratorV1_1 : public V1_1::IVibrator { -public: - MOCK_METHOD(hardware::Return<V1_0::Status>, on, (uint32_t timeoutMs), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, off, (), (override)); - MOCK_METHOD(hardware::Return<bool>, supportsAmplitudeControl, (), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, setAmplitude, (uint8_t amplitude), (override)); - MOCK_METHOD(hardware::Return<void>, perform, - (V1_0::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override)); - MOCK_METHOD(hardware::Return<void>, perform_1_1, - (V1_1::Effect_1_1 effect, V1_0::EffectStrength strength, perform_cb cb), - (override)); -}; - -// ------------------------------------------------------------------------------------------------- - -class VibratorHalWrapperHidlV1_1Test : public Test { -public: - void SetUp() override { - mMockHal = new StrictMock<MockIVibratorV1_1>(); - mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>(); - mWrapper = std::make_unique<vibrator::HidlHalWrapperV1_1>(mMockScheduler, mMockHal); - ASSERT_NE(mWrapper, nullptr); - } - -protected: - std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr; - std::unique_ptr<vibrator::HalWrapper> mWrapper = nullptr; - sp<StrictMock<MockIVibratorV1_1>> mMockHal = nullptr; -}; - -// ------------------------------------------------------------------------------------------------- - -TEST_F(VibratorHalWrapperHidlV1_1Test, TestPerformEffectV1_0) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_1::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback); - - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_1Test, TestPerformEffectV1_1) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform_1_1(Eq(V1_1::Effect_1_1::TICK), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly([](V1_1::Effect_1_1, V1_0::EffectStrength, - MockIVibratorV1_1::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - EXPECT_CALL(*mMockHal.get(), - perform_1_1(Eq(V1_1::Effect_1_1::TICK), Eq(V1_0::EffectStrength::MEDIUM), _)) - .Times(Exactly(1)) - .WillRepeatedly([](V1_1::Effect_1_1, V1_0::EffectStrength, - MockIVibratorV1_1::perform_cb cb) { - cb(V1_0::Status::UNSUPPORTED_OPERATION, 0); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockHal.get(), - perform_1_1(Eq(V1_1::Effect_1_1::TICK), Eq(V1_0::EffectStrength::STRONG), _)) - .Times(Exactly(2)) - .WillOnce([](V1_1::Effect_1_1, V1_0::EffectStrength, - MockIVibratorV1_1::perform_cb cb) { - cb(V1_0::Status::BAD_VALUE, 0); - return hardware::Return<void>(); - }) - .WillRepeatedly( - [](V1_1::Effect_1_1, V1_0::EffectStrength, MockIVibratorV1_1::perform_cb) { - return hardware::Return<void>(hardware::Status::fromExceptionCode(-1)); - }); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - - auto result = mWrapper->performEffect(Effect::TICK, EffectStrength::LIGHT, callback); - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); - - result = mWrapper->performEffect(Effect::TICK, EffectStrength::MEDIUM, callback); - ASSERT_TRUE(result.isUnsupported()); - - result = mWrapper->performEffect(Effect::TICK, EffectStrength::STRONG, callback); - ASSERT_TRUE(result.isFailed()); - - result = mWrapper->performEffect(Effect::TICK, EffectStrength::STRONG, callback); - ASSERT_TRUE(result.isFailed()); - - // Callback not triggered for unsupported and on failure - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_1Test, TestPerformEffectUnsupported) { - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - // Using THUD that is only available in v1.2 - auto result = mWrapper->performEffect(Effect::THUD, EffectStrength::LIGHT, callback); - ASSERT_TRUE(result.isUnsupported()); - // No callback is triggered. - ASSERT_EQ(0, *callbackCounter.get()); -} diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_2Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_2Test.cpp deleted file mode 100644 index dfe3fa0e68..0000000000 --- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_2Test.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "VibratorHalWrapperHidlV1_2Test" - -#include <aidl/android/hardware/vibrator/IVibrator.h> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include <utils/Log.h> - -#include <vibratorservice/VibratorCallbackScheduler.h> -#include <vibratorservice/VibratorHalWrapper.h> - -#include "test_mocks.h" -#include "test_utils.h" - -namespace V1_0 = android::hardware::vibrator::V1_0; -namespace V1_1 = android::hardware::vibrator::V1_1; -namespace V1_2 = android::hardware::vibrator::V1_2; - -using aidl::android::hardware::vibrator::Effect; -using aidl::android::hardware::vibrator::EffectStrength; - -using namespace android; -using namespace std::chrono_literals; -using namespace testing; - -// ------------------------------------------------------------------------------------------------- - -class MockIVibratorV1_2 : public V1_2::IVibrator { -public: - MOCK_METHOD(hardware::Return<V1_0::Status>, on, (uint32_t timeoutMs), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, off, (), (override)); - MOCK_METHOD(hardware::Return<bool>, supportsAmplitudeControl, (), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, setAmplitude, (uint8_t amplitude), (override)); - MOCK_METHOD(hardware::Return<void>, perform, - (V1_0::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override)); - MOCK_METHOD(hardware::Return<void>, perform_1_1, - (V1_1::Effect_1_1 effect, V1_0::EffectStrength strength, perform_cb cb), - (override)); - MOCK_METHOD(hardware::Return<void>, perform_1_2, - (V1_2::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override)); -}; - -// ------------------------------------------------------------------------------------------------- - -class VibratorHalWrapperHidlV1_2Test : public Test { -public: - void SetUp() override { - mMockHal = new StrictMock<MockIVibratorV1_2>(); - mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>(); - mWrapper = std::make_unique<vibrator::HidlHalWrapperV1_2>(mMockScheduler, mMockHal); - ASSERT_NE(mWrapper, nullptr); - } - -protected: - std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr; - std::unique_ptr<vibrator::HalWrapper> mWrapper = nullptr; - sp<StrictMock<MockIVibratorV1_2>> mMockHal = nullptr; -}; - -// ------------------------------------------------------------------------------------------------- - -TEST_F(VibratorHalWrapperHidlV1_2Test, TestPerformEffectV1_0) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_2::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback); - - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_2Test, TestPerformEffectV1_1) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform_1_1(Eq(V1_1::Effect_1_1::TICK), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly([](V1_1::Effect_1_1, V1_0::EffectStrength, - MockIVibratorV1_2::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - auto result = mWrapper->performEffect(Effect::TICK, EffectStrength::LIGHT, callback); - - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_2Test, TestPerformEffectV1_2) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform_1_2(Eq(V1_2::Effect::THUD), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_2::Effect, V1_0::EffectStrength, MockIVibratorV1_2::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - EXPECT_CALL(*mMockHal.get(), - perform_1_2(Eq(V1_2::Effect::THUD), Eq(V1_0::EffectStrength::MEDIUM), _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_2::Effect, V1_0::EffectStrength, MockIVibratorV1_2::perform_cb cb) { - cb(V1_0::Status::UNSUPPORTED_OPERATION, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockHal.get(), - perform_1_2(Eq(V1_2::Effect::THUD), Eq(V1_0::EffectStrength::STRONG), _)) - .Times(Exactly(2)) - .WillOnce([](V1_2::Effect, V1_0::EffectStrength, MockIVibratorV1_2::perform_cb cb) { - cb(V1_0::Status::BAD_VALUE, 10); - return hardware::Return<void>(); - }) - .WillRepeatedly( - [](V1_2::Effect, V1_0::EffectStrength, MockIVibratorV1_2::perform_cb) { - return hardware::Return<void>(hardware::Status::fromExceptionCode(-1)); - }); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - - auto result = mWrapper->performEffect(Effect::THUD, EffectStrength::LIGHT, callback); - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); - - result = mWrapper->performEffect(Effect::THUD, EffectStrength::MEDIUM, callback); - ASSERT_TRUE(result.isUnsupported()); - - result = mWrapper->performEffect(Effect::THUD, EffectStrength::STRONG, callback); - ASSERT_TRUE(result.isFailed()); - - result = mWrapper->performEffect(Effect::THUD, EffectStrength::STRONG, callback); - ASSERT_TRUE(result.isFailed()); - - // Callback not triggered for unsupported and on failure - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_2Test, TestPerformEffectUnsupported) { - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - // Using TEXTURE_TICK that is only available in v1.3 - auto result = mWrapper->performEffect(Effect::TEXTURE_TICK, EffectStrength::LIGHT, callback); - ASSERT_TRUE(result.isUnsupported()); - // No callback is triggered. - ASSERT_EQ(0, *callbackCounter.get()); -} diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp deleted file mode 100644 index 86243326ac..0000000000 --- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "VibratorHalWrapperHidlV1_3Test" - -#include <aidl/android/hardware/vibrator/IVibrator.h> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include <utils/Log.h> -#include <thread> - -#include <vibratorservice/VibratorCallbackScheduler.h> -#include <vibratorservice/VibratorHalWrapper.h> - -#include "test_mocks.h" -#include "test_utils.h" - -namespace V1_0 = android::hardware::vibrator::V1_0; -namespace V1_1 = android::hardware::vibrator::V1_1; -namespace V1_2 = android::hardware::vibrator::V1_2; -namespace V1_3 = android::hardware::vibrator::V1_3; - -using aidl::android::hardware::vibrator::Effect; -using aidl::android::hardware::vibrator::EffectStrength; -using aidl::android::hardware::vibrator::IVibrator; - -using namespace android; -using namespace std::chrono_literals; -using namespace testing; - -// ------------------------------------------------------------------------------------------------- - -class MockIVibratorV1_3 : public V1_3::IVibrator { -public: - MOCK_METHOD(hardware::Return<V1_0::Status>, on, (uint32_t timeoutMs), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, off, (), (override)); - MOCK_METHOD(hardware::Return<bool>, supportsAmplitudeControl, (), (override)); - MOCK_METHOD(hardware::Return<bool>, supportsExternalControl, (), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, setAmplitude, (uint8_t amplitude), (override)); - MOCK_METHOD(hardware::Return<V1_0::Status>, setExternalControl, (bool enabled), (override)); - MOCK_METHOD(hardware::Return<void>, perform, - (V1_0::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override)); - MOCK_METHOD(hardware::Return<void>, perform_1_1, - (V1_1::Effect_1_1 effect, V1_0::EffectStrength strength, perform_cb cb), - (override)); - MOCK_METHOD(hardware::Return<void>, perform_1_2, - (V1_2::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override)); - MOCK_METHOD(hardware::Return<void>, perform_1_3, - (V1_3::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override)); -}; - -// ------------------------------------------------------------------------------------------------- - -class VibratorHalWrapperHidlV1_3Test : public Test { -public: - void SetUp() override { - mMockHal = new StrictMock<MockIVibratorV1_3>(); - mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>(); - mWrapper = std::make_unique<vibrator::HidlHalWrapperV1_3>(mMockScheduler, mMockHal); - ASSERT_NE(mWrapper, nullptr); - } - -protected: - std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr; - std::unique_ptr<vibrator::HalWrapper> mWrapper = nullptr; - sp<StrictMock<MockIVibratorV1_3>> mMockHal = nullptr; -}; - -// ------------------------------------------------------------------------------------------------- - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestSetExternalControl) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(true))) - .Times(Exactly(2)) - .WillOnce([]() { return hardware::Return<V1_0::Status>(V1_0::Status::OK); }) - .WillRepeatedly([]() { - return hardware::Return<V1_0::Status>(V1_0::Status::UNSUPPORTED_OPERATION); - }); - EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(false))) - .Times(Exactly(2)) - .WillOnce([]() { return hardware::Return<V1_0::Status>(V1_0::Status::BAD_VALUE); }) - .WillRepeatedly([]() { - return hardware::Return<V1_0::Status>(hardware::Status::fromExceptionCode(-1)); - }); - } - - ASSERT_TRUE(mWrapper->setExternalControl(true).isOk()); - ASSERT_TRUE(mWrapper->setExternalControl(true).isUnsupported()); - ASSERT_TRUE(mWrapper->setExternalControl(false).isFailed()); - ASSERT_TRUE(mWrapper->setExternalControl(false).isFailed()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoSuccessful) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { return hardware::Return<bool>(true); }); - EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() { - return hardware::Return<bool>(true); - }); - } - - ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL | vibrator::Capabilities::EXTERNAL_CONTROL | - vibrator::Capabilities::EXTERNAL_AMPLITUDE_CONTROL, - mWrapper->getInfo().capabilities.value()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoOnlyAmplitudeControl) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()).Times(Exactly(1)).WillOnce([]() { - return hardware::Return<bool>(true); - }); - EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() { - return hardware::Return<bool>(false); - }); - } - - ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, mWrapper->getInfo().capabilities.value()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoOnlyExternalControl) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()).Times(Exactly(1)).WillOnce([]() { - return hardware::Return<bool>(false); - }); - EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() { - return hardware::Return<bool>(true); - }); - } - - ASSERT_EQ(vibrator::Capabilities::EXTERNAL_CONTROL, mWrapper->getInfo().capabilities.value()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoNoCapabilities) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { return hardware::Return<bool>(false); }); - EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() { - return hardware::Return<bool>(false); - }); - } - - ASSERT_EQ(vibrator::Capabilities::NONE, mWrapper->getInfo().capabilities.value()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoFailed) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { - return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1)); - }); - - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { return hardware::Return<bool>(true); }); - EXPECT_CALL(*mMockHal.get(), supportsExternalControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { - return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1)); - }); - } - - ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed()); - ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoCachesResult) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { return hardware::Return<bool>(true); }); - EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() { - return hardware::Return<bool>(false); - }); - } - - std::vector<std::thread> threads; - for (int i = 0; i < 10; i++) { - threads.push_back( - std::thread([&]() { ASSERT_TRUE(mWrapper->getInfo().capabilities.isOk()); })); - } - std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); }); - - ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, mWrapper->getInfo().capabilities.value()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoDoesNotCacheFailedResult) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { - return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1)); - }); - - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { return hardware::Return<bool>(true); }); - EXPECT_CALL(*mMockHal.get(), supportsExternalControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { - return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1)); - }); - - EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { return hardware::Return<bool>(true); }); - EXPECT_CALL(*mMockHal.get(), supportsExternalControl()) - .Times(Exactly(1)) - .WillRepeatedly([]() { return hardware::Return<bool>(false); }); - } - - // Call to supportsAmplitudeControl failed. - ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed()); - - // Call to supportsExternalControl failed. - ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed()); - - // Returns successful result from third call. - ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, mWrapper->getInfo().capabilities.value()); - - // Returns cached successful result. - ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, mWrapper->getInfo().capabilities.value()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestPerformEffectV1_0) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback); - - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestPerformEffectV1_1) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform_1_1(Eq(V1_1::Effect_1_1::TICK), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly([](V1_1::Effect_1_1, V1_0::EffectStrength, - MockIVibratorV1_3::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - auto result = mWrapper->performEffect(Effect::TICK, EffectStrength::LIGHT, callback); - - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestPerformEffectV1_2) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform_1_2(Eq(V1_2::Effect::THUD), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_2::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - auto result = mWrapper->performEffect(Effect::THUD, EffectStrength::LIGHT, callback); - - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); -} - -TEST_F(VibratorHalWrapperHidlV1_3Test, TestPerformEffectV1_3) { - { - InSequence seq; - EXPECT_CALL(*mMockHal.get(), - perform_1_3(Eq(V1_3::Effect::TEXTURE_TICK), Eq(V1_0::EffectStrength::LIGHT), _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_3::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) { - cb(V1_0::Status::OK, 10); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms))) - .Times(Exactly(1)) - .WillRepeatedly(vibrator::TriggerSchedulerCallback()); - EXPECT_CALL(*mMockHal.get(), - perform_1_3(Eq(V1_3::Effect::TEXTURE_TICK), Eq(V1_0::EffectStrength::MEDIUM), - _)) - .Times(Exactly(1)) - .WillRepeatedly( - [](V1_3::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) { - cb(V1_0::Status::UNSUPPORTED_OPERATION, 0); - return hardware::Return<void>(); - }); - EXPECT_CALL(*mMockHal.get(), - perform_1_3(Eq(V1_3::Effect::TEXTURE_TICK), Eq(V1_0::EffectStrength::STRONG), - _)) - .Times(Exactly(2)) - .WillOnce([](V1_3::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) { - cb(V1_0::Status::BAD_VALUE, 0); - return hardware::Return<void>(); - }) - .WillRepeatedly( - [](V1_3::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb) { - return hardware::Return<void>(hardware::Status::fromExceptionCode(-1)); - }); - } - - std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); - auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); - - auto result = mWrapper->performEffect(Effect::TEXTURE_TICK, EffectStrength::LIGHT, callback); - ASSERT_TRUE(result.isOk()); - ASSERT_EQ(10ms, result.value()); - ASSERT_EQ(1, *callbackCounter.get()); - - result = mWrapper->performEffect(Effect::TEXTURE_TICK, EffectStrength::MEDIUM, callback); - ASSERT_TRUE(result.isUnsupported()); - - result = mWrapper->performEffect(Effect::TEXTURE_TICK, EffectStrength::STRONG, callback); - ASSERT_TRUE(result.isFailed()); - - result = mWrapper->performEffect(Effect::TEXTURE_TICK, EffectStrength::STRONG, callback); - ASSERT_TRUE(result.isFailed()); - - // Callback not triggered for unsupported and on failure - ASSERT_EQ(1, *callbackCounter.get()); -} diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp index 879d2d0fa7..be8fb3ea1d 100644 --- a/vulkan/libvulkan/Android.bp +++ b/vulkan/libvulkan/Android.bp @@ -22,6 +22,13 @@ package { default_applicable_licenses: ["frameworks_native_license"], } +// Expose internal header files to test testing binary +cc_library_headers { + name: "libvulkanprivate_headers-testing", + export_include_dirs: ["."], + visibility: ["//frameworks/native/vulkan/tests"], +} + ndk_library { name: "libvulkan", symbol_file: "libvulkan.map.txt", diff --git a/vulkan/libvulkan/TEST_MAPPING b/vulkan/libvulkan/TEST_MAPPING new file mode 100644 index 0000000000..16e342b7c0 --- /dev/null +++ b/vulkan/libvulkan/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "libvulkan_test" + } + ] +} diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 09b0a145af..5e2b55ef75 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -1413,115 +1413,138 @@ static void DestroySwapchainInternal(VkDevice device, allocator->pfnFree(allocator->pUserData, swapchain); } -static VkResult getProducerUsage(const VkDevice& device, - const VkSwapchainCreateInfoKHR* create_info, - const VkSwapchainImageUsageFlagsANDROID swapchain_image_usage, - bool create_protected_swapchain, - uint64_t* producer_usage) { - // Get the physical device to query the appropriate producer usage - const VkPhysicalDevice& pdev = GetData(device).driver_physical_device; - const InstanceData& instance_data = GetData(pdev); - const InstanceDriverTable& instance_dispatch = instance_data.driver; - if (instance_dispatch.GetPhysicalDeviceImageFormatProperties2 || - instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR) { - // Look through the create_info pNext chain passed to createSwapchainKHR - // for an image compression control struct. - // if one is found AND the appropriate extensions are enabled, create a - // VkImageCompressionControlEXT structure to pass on to - // GetPhysicalDeviceImageFormatProperties2 - void* compression_control_pNext = nullptr; - VkImageCompressionControlEXT image_compression = {}; - const VkSwapchainCreateInfoKHR* create_infos = create_info; - while (create_infos->pNext) { - create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>(create_infos->pNext); - switch (create_infos->sType) { - case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: { - const VkImageCompressionControlEXT* compression_infos = - reinterpret_cast<const VkImageCompressionControlEXT*>(create_infos); - image_compression = *compression_infos; - image_compression.pNext = nullptr; - compression_control_pNext = &image_compression; - } break; - default: - // Ignore all other info structs - break; - } +static VkResult getProducerUsageGPDIFP2( + const VkPhysicalDevice& pdev, + const VkSwapchainCreateInfoKHR* create_info, + const VkSwapchainImageUsageFlagsANDROID swapchain_image_usage, + bool create_protected_swapchain, + uint64_t* producer_usage) { + // Look through the create_info pNext chain passed to createSwapchainKHR + // for an image compression control struct. + // if one is found AND the appropriate extensions are enabled, create a + // VkImageCompressionControlEXT structure to pass on to + // GetPhysicalDeviceImageFormatProperties2 + void* compression_control_pNext = nullptr; + VkImageCompressionControlEXT image_compression = {}; + const VkSwapchainCreateInfoKHR* create_infos = create_info; + while (create_infos->pNext) { + create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>( + create_infos->pNext); + switch (create_infos->sType) { + case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: { + const VkImageCompressionControlEXT* compression_infos = + reinterpret_cast<const VkImageCompressionControlEXT*>( + create_infos); + image_compression = *compression_infos; + image_compression.pNext = nullptr; + compression_control_pNext = &image_compression; + } break; + default: + // Ignore all other info structs + break; } + } - // call GetPhysicalDeviceImageFormatProperties2KHR - VkPhysicalDeviceExternalImageFormatInfo external_image_format_info = { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, - .pNext = compression_control_pNext, - .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, - }; + // call GetPhysicalDeviceImageFormatProperties2KHR + VkPhysicalDeviceExternalImageFormatInfo external_image_format_info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, + .pNext = compression_control_pNext, + .handleType = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, + }; - // AHB does not have an sRGB format so we can't pass it to GPDIFP - // We need to convert the format to unorm if it is srgb - VkFormat format = create_info->imageFormat; - if (format == VK_FORMAT_R8G8B8A8_SRGB) { - format = VK_FORMAT_R8G8B8A8_UNORM; - } + // AHB does not have an sRGB format so we can't pass it to GPDIFP + // We need to convert the format to unorm if it is srgb + VkFormat format = create_info->imageFormat; + if (format == VK_FORMAT_R8G8B8A8_SRGB) { + format = VK_FORMAT_R8G8B8A8_UNORM; + } - VkPhysicalDeviceImageFormatInfo2 image_format_info = { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, - .pNext = &external_image_format_info, - .format = format, - .type = VK_IMAGE_TYPE_2D, - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = create_info->imageUsage, - .flags = create_protected_swapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u, - }; + VkPhysicalDeviceImageFormatInfo2 image_format_info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + .pNext = &external_image_format_info, + .format = format, + .type = VK_IMAGE_TYPE_2D, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = create_info->imageUsage, + .flags = + create_protected_swapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u, + }; - // If supporting mutable format swapchain add the mutable format flag - if (create_info->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) { - image_format_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; - image_format_info.flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR; - } + // If supporting mutable format swapchain add the mutable format flag + if (create_info->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) { + image_format_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + image_format_info.flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR; + } - VkAndroidHardwareBufferUsageANDROID ahb_usage; - ahb_usage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID; - ahb_usage.pNext = nullptr; + VkAndroidHardwareBufferUsageANDROID ahb_usage; + ahb_usage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID; + ahb_usage.pNext = nullptr; - VkImageFormatProperties2 image_format_properties; - image_format_properties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; - image_format_properties.pNext = &ahb_usage; + VkImageFormatProperties2 image_format_properties; + image_format_properties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; + image_format_properties.pNext = &ahb_usage; - VkResult result = GetPhysicalDeviceImageFormatProperties2( - pdev, &image_format_info, &image_format_properties); - if (result != VK_SUCCESS) { - ALOGE( - "VkGetPhysicalDeviceImageFormatProperties2 for AHB usage " - "failed: %d", - result); - return VK_ERROR_SURFACE_LOST_KHR; - } + VkResult result = GetPhysicalDeviceImageFormatProperties2( + pdev, &image_format_info, &image_format_properties); + if (result != VK_SUCCESS) { + ALOGE( + "VkGetPhysicalDeviceImageFormatProperties2 for AHB usage " + "failed: %d", + result); + return VK_ERROR_SURFACE_LOST_KHR; + } + // Determine if USAGE_FRONT_BUFFER is needed. + // GPDIFP2 has no means of using VkSwapchainImageUsageFlagsANDROID when + // querying for producer_usage. So androidHardwareBufferUsage will not + // contain USAGE_FRONT_BUFFER. We need to manually check for usage here. + if (!(swapchain_image_usage & + VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)) { + *producer_usage = ahb_usage.androidHardwareBufferUsage; + return VK_SUCCESS; + } - // Determine if USAGE_FRONT_BUFFER is needed. - // GPDIFP2 has no means of using VkSwapchainImageUsageFlagsANDROID when - // querying for producer_usage. So androidHardwareBufferUsage will not - // contain USAGE_FRONT_BUFFER. We need to manually check for usage here. - if (!(swapchain_image_usage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)) { - *producer_usage = ahb_usage.androidHardwareBufferUsage; - return VK_SUCCESS; - } + // Check if USAGE_FRONT_BUFFER is supported for this swapchain + AHardwareBuffer_Desc ahb_desc = { + .width = create_info->imageExtent.width, + .height = create_info->imageExtent.height, + .layers = create_info->imageArrayLayers, + .format = create_info->imageFormat, + .usage = ahb_usage.androidHardwareBufferUsage | + AHARDWAREBUFFER_USAGE_FRONT_BUFFER, + .stride = 0, // stride is always ignored when calling isSupported() + }; - // Check if USAGE_FRONT_BUFFER is supported for this swapchain - AHardwareBuffer_Desc ahb_desc = { - .width = create_info->imageExtent.width, - .height = create_info->imageExtent.height, - .layers = create_info->imageArrayLayers, - .format = create_info->imageFormat, - .usage = ahb_usage.androidHardwareBufferUsage | AHARDWAREBUFFER_USAGE_FRONT_BUFFER, - .stride = 0, // stride is always ignored when calling isSupported() - }; + // If FRONT_BUFFER is not supported in the GPDIFP2 path + // then we need to fallback to GetSwapchainGrallocUsageXAndroid + if (AHardwareBuffer_isSupported(&ahb_desc)) { + *producer_usage = ahb_usage.androidHardwareBufferUsage; + *producer_usage |= AHARDWAREBUFFER_USAGE_FRONT_BUFFER; + return VK_SUCCESS; + } + + return VK_ERROR_FORMAT_NOT_SUPPORTED; +} + +static VkResult getProducerUsage(const VkDevice& device, + const VkSwapchainCreateInfoKHR* create_info, + const VkSwapchainImageUsageFlagsANDROID swapchain_image_usage, + bool create_protected_swapchain, + uint64_t* producer_usage) { + // Get the physical device to query the appropriate producer usage + const VkPhysicalDevice& pdev = GetData(device).driver_physical_device; + const InstanceData& instance_data = GetData(pdev); + const InstanceDriverTable& instance_dispatch = instance_data.driver; - // If FRONT_BUFFER is not supported, - // then we need to call GetSwapchainGrallocUsageXAndroid below - if (AHardwareBuffer_isSupported(&ahb_desc)) { - *producer_usage = ahb_usage.androidHardwareBufferUsage; - *producer_usage |= AHARDWAREBUFFER_USAGE_FRONT_BUFFER; + if (instance_dispatch.GetPhysicalDeviceImageFormatProperties2 || + instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR) { + VkResult result = + getProducerUsageGPDIFP2(pdev, create_info, swapchain_image_usage, + create_protected_swapchain, producer_usage); + if (result == VK_SUCCESS) { return VK_SUCCESS; } + // Fall through to gralloc path on error } uint64_t native_usage = 0; diff --git a/vulkan/scripts/code_generator.py b/vulkan/scripts/code_generator.py index 2a017d2259..051816de87 100755 --- a/vulkan/scripts/code_generator.py +++ b/vulkan/scripts/code_generator.py @@ -21,6 +21,7 @@ import api_generator import driver_generator import generator_common import null_generator +import vkjson_generator if __name__ == '__main__': generator_common.parse_vulkan_registry() @@ -30,3 +31,6 @@ if __name__ == '__main__': driver_generator.gen_cpp() null_generator.gen_h() null_generator.gen_cpp() + vkjson_generator.gen_h() + vkjson_generator.gen_cc() + vkjson_generator.gen_instance_cc() diff --git a/vulkan/scripts/vk.py b/vulkan/scripts/vk.py new file mode 100644 index 0000000000..983e0dc296 --- /dev/null +++ b/vulkan/scripts/vk.py @@ -0,0 +1,968 @@ +import ctypes +import dataclasses +import enum +from typing import List + +dataclass = dataclasses.dataclass +Enum = enum.Enum + +# TODO(b/401184058): Automate this file for generating the vulkan structs graph from vk.xml +VK_UUID_SIZE = 16 +VK_LUID_SIZE = 16 + +VkImageLayout = Enum +uint8_t = ctypes.c_uint8 +uint32_t = ctypes.c_uint32 +VkFlags = uint32_t +VkMemoryPropertyFlags = VkFlags +VkMemoryHeapFlags = VkFlags +int32_t = int +uint64_t = ctypes.c_uint64 +VkBool32 = bool +VkDeviceSize = ctypes.c_uint64 +size_t = int +VkSampleCountFlags = ctypes.c_uint32 +VkFormatFeatureFlags = ctypes.c_uint32 +VkQueueFlags = ctypes.c_uint32 +VkShaderStageFlags = ctypes.c_uint32 +VkSubgroupFeatureFlags = ctypes.c_uint32 +VkResolveModeFlags = ctypes.c_uint32 +float_t = ctypes.c_float +VkShaderFloatControlsIndependence = Enum +VkPointClippingBehavior = Enum +VkPhysicalDeviceType = Enum +VkDriverId = Enum +VkPipelineRobustnessBufferBehavior = Enum + + +@dataclass +class ConformanceVersion: + major: uint8_t + minor: uint8_t + subminor: uint8_t + patch: uint8_t + + +@dataclass +class VkExtent3D: + width: uint32_t + height: uint32_t + depth: uint32_t + + +@dataclass +class VkPhysicalDeviceLimits: + maxImageDimension1D: uint32_t + maxImageDimension2D: uint32_t + maxImageDimension3D: uint32_t + maxImageDimensionCube: uint32_t + maxImageArrayLayers: uint32_t + maxTexelBufferElements: uint32_t + maxUniformBufferRange: uint32_t + maxStorageBufferRange: uint32_t + maxPushConstantsSize: uint32_t + maxMemoryAllocationCount: uint32_t + maxSamplerAllocationCount: uint32_t + bufferImageGranularity: VkDeviceSize + sparseAddressSpaceSize: VkDeviceSize + maxBoundDescriptorSets: uint32_t + maxPerStageDescriptorSamplers: uint32_t + maxPerStageDescriptorUniformBuffers: uint32_t + maxPerStageDescriptorStorageBuffers: uint32_t + maxPerStageDescriptorSampledImages: uint32_t + maxPerStageDescriptorStorageImages: uint32_t + maxPerStageDescriptorInputAttachments: uint32_t + maxPerStageResources: uint32_t + maxDescriptorSetSamplers: uint32_t + maxDescriptorSetUniformBuffers: uint32_t + maxDescriptorSetUniformBuffersDynamic: uint32_t + maxDescriptorSetStorageBuffers: uint32_t + maxDescriptorSetStorageBuffersDynamic: uint32_t + maxDescriptorSetSampledImages: uint32_t + maxDescriptorSetStorageImages: uint32_t + maxDescriptorSetInputAttachments: uint32_t + maxVertexInputAttributes: uint32_t + maxVertexInputBindings: uint32_t + maxVertexInputAttributeOffset: uint32_t + maxVertexInputBindingStride: uint32_t + maxVertexOutputComponents: uint32_t + maxTessellationGenerationLevel: uint32_t + maxTessellationPatchSize: uint32_t + maxTessellationControlPerVertexInputComponents: uint32_t + maxTessellationControlPerVertexOutputComponents: uint32_t + maxTessellationControlPerPatchOutputComponents: uint32_t + maxTessellationControlTotalOutputComponents: uint32_t + maxTessellationEvaluationInputComponents: uint32_t + maxTessellationEvaluationOutputComponents: uint32_t + maxGeometryShaderInvocations: uint32_t + maxGeometryInputComponents: uint32_t + maxGeometryOutputComponents: uint32_t + maxGeometryOutputVertices: uint32_t + maxGeometryTotalOutputComponents: uint32_t + maxFragmentInputComponents: uint32_t + maxFragmentOutputAttachments: uint32_t + maxFragmentDualSrcAttachments: uint32_t + maxFragmentCombinedOutputResources: uint32_t + maxComputeSharedMemorySize: uint32_t + maxComputeWorkGroupCount: uint32_t*3 + maxComputeWorkGroupInvocations: uint32_t + maxComputeWorkGroupSize: uint32_t*3 + subPixelPrecisionBits: uint32_t + subTexelPrecisionBits: uint32_t + mipmapPrecisionBits: uint32_t + maxDrawIndexedIndexValue: uint32_t + maxDrawIndirectCount: uint32_t + maxSamplerLodBias: float + maxSamplerAnisotropy: float + maxViewports: uint32_t + maxViewportDimensions: uint32_t*2 + viewportBoundsRange: float_t*2 + viewportSubPixelBits: uint32_t + minMemoryMapAlignment: size_t + minTexelBufferOffsetAlignment: VkDeviceSize + minUniformBufferOffsetAlignment: VkDeviceSize + minStorageBufferOffsetAlignment: VkDeviceSize + minTexelOffset: int32_t + maxTexelOffset: uint32_t + minTexelGatherOffset: int32_t + maxTexelGatherOffset: uint32_t + minInterpolationOffset: float + maxInterpolationOffset: float + subPixelInterpolationOffsetBits: uint32_t + maxFramebufferWidth: uint32_t + maxFramebufferHeight: uint32_t + maxFramebufferLayers: uint32_t + framebufferColorSampleCounts: VkSampleCountFlags + framebufferDepthSampleCounts: VkSampleCountFlags + framebufferStencilSampleCounts: VkSampleCountFlags + framebufferNoAttachmentsSampleCounts: VkSampleCountFlags + maxColorAttachments: uint32_t + sampledImageColorSampleCounts: VkSampleCountFlags + sampledImageIntegerSampleCounts: VkSampleCountFlags + sampledImageDepthSampleCounts: VkSampleCountFlags + sampledImageStencilSampleCounts: VkSampleCountFlags + storageImageSampleCounts: VkSampleCountFlags + maxSampleMaskWords: uint32_t + timestampComputeAndGraphics: VkBool32 + timestampPeriod: float + maxClipDistances: uint32_t + maxCullDistances: uint32_t + maxCombinedClipAndCullDistances: uint32_t + discreteQueuePriorities: uint32_t + pointSizeRange: float_t*2 + lineWidthRange: float_t*2 + pointSizeGranularity: float + lineWidthGranularity: float + strictLines: VkBool32 + standardSampleLocations: VkBool32 + optimalBufferCopyOffsetAlignment: VkDeviceSize + optimalBufferCopyRowPitchAlignment: VkDeviceSize + nonCoherentAtomSize: VkDeviceSize + + +@dataclass +class VkPhysicalDeviceShaderDrawParameterFeatures: + shaderDrawParameters: VkBool32 + + +@dataclass +class VkExtensionProperties: + extensionName: str + specVersion: uint32_t + + +@dataclass +class VkFormatProperties: + linearTilingFeatures: VkFormatFeatureFlags + optimalTilingFeatures: VkFormatFeatureFlags + bufferFeatures: VkFormatFeatureFlags + + +@dataclass +class VkLayerProperties: + layerName: str + specVersion: uint32_t + implementationVersion: uint32_t + description: str + + +@dataclass +class VkQueueFamilyProperties: + queueFlags: VkQueueFlags + queueCount: uint32_t + timestampValidBits: uint32_t + minImageTransferGranularity: VkExtent3D + + +@dataclass +class VkPhysicalDeviceSparseProperties: + residencyStandard2DBlockShape: VkBool32 + residencyStandard2DMultisampleBlockShape: VkBool32 + residencyStandard3DBlockShape: VkBool32 + residencyAlignedMipSize: VkBool32 + residencyNonResidentStrict: VkBool32 + + +@dataclass +class VkImageFormatProperties: + maxExtent: VkExtent3D + maxMipLevels: uint32_t + maxArrayLayers: uint32_t + sampleCounts: VkSampleCountFlags + maxResourceSize: VkDeviceSize + + +@dataclass +class VkPhysicalDeviceSamplerYcbcrConversionFeatures: + samplerYcbcrConversion: VkBool32 + + +@dataclass +class VkPhysicalDeviceIDProperties: + deviceUUID: uint8_t*VK_UUID_SIZE + driverUUID: uint8_t*VK_UUID_SIZE + deviceLUID: uint8_t*VK_LUID_SIZE + deviceNodeMask: uint32_t + deviceLUIDValid: VkBool32 + + +@dataclass +class VkPhysicalDeviceMaintenance3Properties: + maxPerSetDescriptors: uint32_t + maxMemoryAllocationSize: VkDeviceSize + + +@dataclass +class VkPhysicalDevice16BitStorageFeatures: + storageBuffer16BitAccess: VkBool32 + uniformAndStorageBuffer16BitAccess: VkBool32 + storagePushConstant16: VkBool32 + storageInputOutput16: VkBool32 + + +@dataclass +class VkPhysicalDeviceMultiviewFeatures: + multiview: VkBool32 + multiviewGeometryShader: VkBool32 + multiviewTessellationShader: VkBool32 + + +@dataclass +class VkPhysicalDeviceSubgroupProperties: + subgroupSize: uint32_t + supportedStages: VkShaderStageFlags + supportedOperations: VkSubgroupFeatureFlags + quadOperationsInAllStages: VkBool32 + + +@dataclass +class VkPhysicalDevicePointClippingProperties: + pointClippingBehavior: VkPointClippingBehavior + + +@dataclass +class VkPhysicalDeviceMultiviewProperties: + maxMultiviewViewCount: uint32_t + maxMultiviewInstanceIndex: uint32_t + + +@dataclass +class VkMemoryType: + propertyFlags: VkMemoryPropertyFlags + heapIndex: uint32_t + + +@dataclass +class VkMemoryHeap: + size: VkDeviceSize + flags: VkMemoryHeapFlags + + +@dataclass +class VkPhysicalDeviceMemoryProperties: + memoryTypeCount: uint32_t + memoryTypes: List[VkMemoryType] + memoryHeapCount: uint32_t + memoryHeaps: List[VkMemoryHeap] + + +@dataclass +class VkPhysicalDeviceProperties: + apiVersion: uint32_t + driverVersion: uint32_t + vendorID: uint32_t + deviceID: uint32_t + deviceType: VkPhysicalDeviceType + deviceName: str + pipelineCacheUUID: uint8_t + limits: VkPhysicalDeviceLimits + sparseProperties: VkPhysicalDeviceSparseProperties + + +@dataclass +class VkPhysicalDeviceFeatures: + robustBufferAccess: VkBool32 + fullDrawIndexUint32: VkBool32 + imageCubeArray: VkBool32 + independentBlend: VkBool32 + geometryShader: VkBool32 + tessellationShader: VkBool32 + sampleRateShading: VkBool32 + dualSrcBlend: VkBool32 + logicOp: VkBool32 + multiDrawIndirect: VkBool32 + drawIndirectFirstInstance: VkBool32 + depthClamp: VkBool32 + depthBiasClamp: VkBool32 + fillModeNonSolid: VkBool32 + depthBounds: VkBool32 + wideLines: VkBool32 + largePoints: VkBool32 + alphaToOne: VkBool32 + multiViewport: VkBool32 + samplerAnisotropy: VkBool32 + textureCompressionETC2: VkBool32 + textureCompressionASTC_LDR: VkBool32 + textureCompressionBC: VkBool32 + occlusionQueryPrecise: VkBool32 + pipelineStatisticsQuery: VkBool32 + vertexPipelineStoresAndAtomics: VkBool32 + fragmentStoresAndAtomics: VkBool32 + shaderTessellationAndGeometryPointSize: VkBool32 + shaderImageGatherExtended: VkBool32 + shaderStorageImageExtendedFormats: VkBool32 + shaderStorageImageMultisample: VkBool32 + shaderStorageImageReadWithoutFormat: VkBool32 + shaderStorageImageWriteWithoutFormat: VkBool32 + shaderUniformBufferArrayDynamicIndexing: VkBool32 + shaderSampledImageArrayDynamicIndexing: VkBool32 + shaderStorageBufferArrayDynamicIndexing: VkBool32 + shaderStorageImageArrayDynamicIndexing: VkBool32 + shaderClipDistance: VkBool32 + shaderCullDistance: VkBool32 + shaderFloat64: VkBool32 + shaderInt64: VkBool32 + shaderInt16: VkBool32 + shaderResourceResidency: VkBool32 + shaderResourceMinLod: VkBool32 + sparseBinding: VkBool32 + sparseResidencyBuffer: VkBool32 + sparseResidencyImage2D: VkBool32 + sparseResidencyImage3D: VkBool32 + sparseResidency2Samples: VkBool32 + sparseResidency4Samples: VkBool32 + sparseResidency8Samples: VkBool32 + sparseResidency16Samples: VkBool32 + sparseResidencyAliased: VkBool32 + variableMultisampleRate: VkBool32 + inheritedQueries: VkBool32 + + +@dataclass +class VkPhysicalDeviceShaderFloat16Int8Features: + shaderFloat16: VkBool32 + shaderInt8: VkBool32 + + +@dataclass +class VkPhysicalDeviceProtectedMemoryFeatures: + protectedMemory: VkBool32 + + +@dataclass +class VkPhysicalDeviceVariablePointersFeatures: + variablePointersStorageBuffer: VkBool32 + variablePointers: VkBool32 + + +@dataclass +class VkPhysicalDeviceImage2DViewOf3DFeaturesEXT: + image2DViewOf3D: VkBool32 + sampler2DViewOf3D: VkBool32 + + +@dataclass +class VkPhysicalDeviceCustomBorderColorFeaturesEXT: + customBorderColors: VkBool32 + customBorderColorWithoutFormat: VkBool32 + + +@dataclass +class VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT: + primitiveTopologyListRestart: VkBool32 + primitiveTopologyPatchListRestart: VkBool32 + + +@dataclass +class VkPhysicalDeviceProvokingVertexFeaturesEXT: + provokingVertexLast: VkBool32 + transformFeedbackPreservesProvokingVertex: VkBool32 + + +@dataclass +class VkPhysicalDeviceIndexTypeUint8Features: + indexTypeUint8: VkBool32 + + +@dataclass +class VkPhysicalDeviceVertexAttributeDivisorFeatures: + vertexAttributeInstanceRateDivisor: VkBool32 + vertexAttributeInstanceRateZeroDivisor: VkBool32 + + +@dataclass +class VkPhysicalDeviceTransformFeedbackFeaturesEXT: + transformFeedback: VkBool32 + geometryStreams: VkBool32 + + +@dataclass +class VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR: + shaderSubgroupUniformControlFlow: VkBool32 + + +@dataclass +class VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures: + shaderSubgroupExtendedTypes: VkBool32 + + +@dataclass +class VkPhysicalDevice8BitStorageFeatures: + storageBuffer8BitAccess: VkBool32 + uniformAndStorageBuffer8BitAccess: VkBool32 + storagePushConstant8: VkBool32 + + +@dataclass +class VkPhysicalDeviceShaderIntegerDotProductFeatures: + shaderIntegerDotProduct: VkBool32 + + +@dataclass +class VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG: + relaxedLineRasterization: VkBool32 + + +@dataclass +class VkPhysicalDeviceLineRasterizationFeatures: + rectangularLines: VkBool32 + bresenhamLines: VkBool32 + smoothLines: VkBool32 + stippledRectangularLines: VkBool32 + stippledBresenhamLines: VkBool32 + stippledSmoothLines: VkBool32 + + +@dataclass +class VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT: + primitivesGeneratedQuery: VkBool32 + primitivesGeneratedQueryWithRasterizerDiscard: VkBool32 + primitivesGeneratedQueryWithNonZeroStreams: VkBool32 + + +@dataclass +class VkPhysicalDeviceFloatControlsProperties: + denormBehaviorIndependence : VkShaderFloatControlsIndependence + roundingModeIndependence : VkShaderFloatControlsIndependence + shaderSignedZeroInfNanPreserveFloat16 : VkBool32 + shaderSignedZeroInfNanPreserveFloat32 : VkBool32 + shaderSignedZeroInfNanPreserveFloat64 : VkBool32 + shaderDenormPreserveFloat16 : VkBool32 + shaderDenormPreserveFloat32 : VkBool32 + shaderDenormPreserveFloat64 : VkBool32 + shaderDenormFlushToZeroFloat16 : VkBool32 + shaderDenormFlushToZeroFloat32 : VkBool32 + shaderDenormFlushToZeroFloat64 : VkBool32 + shaderRoundingModeRTEFloat16 : VkBool32 + shaderRoundingModeRTEFloat32 : VkBool32 + shaderRoundingModeRTEFloat64 :VkBool32 + shaderRoundingModeRTZFloat16 : VkBool32 + shaderRoundingModeRTZFloat32 : VkBool32 + shaderRoundingModeRTZFloat64 : VkBool32 + + +@dataclass +class VkPhysicalDeviceVulkan11Properties: + deviceUUID : uint8_t*VK_UUID_SIZE + driverUUID : uint8_t*VK_UUID_SIZE + deviceLUID : uint8_t*VK_LUID_SIZE + deviceNodeMask : uint32_t + deviceLUIDValid : VkBool32 + subgroupSize : uint32_t + subgroupSupportedStages : VkShaderStageFlags + subgroupSupportedOperations : VkSubgroupFeatureFlags + subgroupQuadOperationsInAllStages : VkBool32 + pointClippingBehavior : VkPointClippingBehavior + maxMultiviewViewCount : uint32_t + maxMultiviewInstanceIndex :uint32_t + protectedNoFault : VkBool32 + maxPerSetDescriptors : uint32_t + maxMemoryAllocationSize : VkDeviceSize + + +@dataclass +class VkPhysicalDeviceVulkan11Features: + storageBuffer16BitAccess: VkBool32 + uniformAndStorageBuffer16BitAccess: VkBool32 + storagePushConstant16: VkBool32 + storageInputOutput16: VkBool32 + multiview: VkBool32 + multiviewGeometryShader: VkBool32 + multiviewTessellationShader: VkBool32 + variablePointersStorageBuffer: VkBool32 + variablePointers: VkBool32 + protectedMemory: VkBool32 + samplerYcbcrConversion: VkBool32 + shaderDrawParameters: VkBool32 + + +@dataclass +class VkPhysicalDeviceVulkan12Properties: + driverID: VkDriverId + driverName: str + driverInfo: str + conformanceVersion: ConformanceVersion + denormBehaviorIndependence: VkShaderFloatControlsIndependence + roundingModeIndependence: VkShaderFloatControlsIndependence + shaderSignedZeroInfNanPreserveFloat16: VkBool32 + shaderSignedZeroInfNanPreserveFloat32: VkBool32 + shaderSignedZeroInfNanPreserveFloat64: VkBool32 + shaderDenormPreserveFloat16: VkBool32 + shaderDenormPreserveFloat32: VkBool32 + shaderDenormPreserveFloat64: VkBool32 + shaderDenormFlushToZeroFloat16: VkBool32 + shaderDenormFlushToZeroFloat32: VkBool32 + shaderDenormFlushToZeroFloat64: VkBool32 + shaderRoundingModeRTEFloat16: VkBool32 + shaderRoundingModeRTEFloat32: VkBool32 + shaderRoundingModeRTEFloat64: VkBool32 + shaderRoundingModeRTZFloat16: VkBool32 + shaderRoundingModeRTZFloat32: VkBool32 + shaderRoundingModeRTZFloat64: VkBool32 + maxUpdateAfterBindDescriptorsInAllPools: uint32_t + shaderUniformBufferArrayNonUniformIndexingNative: VkBool32 + shaderSampledImageArrayNonUniformIndexingNative: VkBool32 + shaderStorageBufferArrayNonUniformIndexingNative: VkBool32 + shaderStorageImageArrayNonUniformIndexingNative: VkBool32 + shaderInputAttachmentArrayNonUniformIndexingNative: VkBool32 + robustBufferAccessUpdateAfterBind: VkBool32 + quadDivergentImplicitLod: VkBool32 + 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: uint32_t + supportedDepthResolveModes: VkResolveModeFlags + supportedStencilResolveModes: VkResolveModeFlags + independentResolveNone: VkBool32 + independentResolve: VkBool32 + filterMinmaxSingleComponentFormats: VkBool32 + filterMinmaxImageComponentMapping: VkBool32 + maxTimelineSemaphoreValueDifference: uint64_t + framebufferIntegerColorSampleCounts: VkSampleCountFlags + + +@dataclass +class VkPhysicalDeviceVulkan12Features: + samplerMirrorClampToEdge: VkBool32 + drawIndirectCount: VkBool32 + storageBuffer8BitAccess: VkBool32 + uniformAndStorageBuffer8BitAccess: VkBool32 + storagePushConstant8: VkBool32 + shaderBufferInt64Atomics: VkBool32 + shaderSharedInt64Atomics: VkBool32 + shaderFloat16: VkBool32 + shaderInt8: VkBool32 + descriptorIndexing: 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: VkBool32 + samplerFilterMinmax: VkBool32 + scalarBlockLayout: VkBool32 + imagelessFramebuffer: VkBool32 + uniformBufferStandardLayout: VkBool32 + shaderSubgroupExtendedTypes: VkBool32 + separateDepthStencilLayouts: VkBool32 + hostQueryReset: VkBool32 + timelineSemaphore: VkBool32 + bufferDeviceAddress: VkBool32 + bufferDeviceAddressCaptureReplay: VkBool32 + bufferDeviceAddressMultiDevice: VkBool32 + vulkanMemoryModel: VkBool32 + vulkanMemoryModelDeviceScope: VkBool32 + vulkanMemoryModelAvailabilityVisibilityChains: VkBool32 + shaderOutputViewportIndex: VkBool32 + shaderOutputLayer: VkBool32 + subgroupBroadcastDynamicId: VkBool32 + + +@dataclass +class VkPhysicalDeviceVulkan13Properties: + minSubgroupSize: uint32_t + maxSubgroupSize: uint32_t + maxComputeWorkgroupSubgroups: uint32_t + requiredSubgroupSizeStages: VkShaderStageFlags + maxInlineUniformBlockSize: uint32_t + maxPerStageDescriptorInlineUniformBlocks: uint32_t + maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks: uint32_t + maxDescriptorSetInlineUniformBlocks: uint32_t + maxDescriptorSetUpdateAfterBindInlineUniformBlocks: uint32_t + maxInlineUniformTotalSize: uint32_t + integerDotProduct8BitUnsignedAccelerated: VkBool32 + integerDotProduct8BitSignedAccelerated: VkBool32 + integerDotProduct8BitMixedSignednessAccelerated: VkBool32 + integerDotProduct4x8BitPackedUnsignedAccelerated: VkBool32 + integerDotProduct4x8BitPackedSignedAccelerated: VkBool32 + integerDotProduct4x8BitPackedMixedSignednessAccelerated: VkBool32 + integerDotProduct16BitUnsignedAccelerated: VkBool32 + integerDotProduct16BitSignedAccelerated: VkBool32 + integerDotProduct16BitMixedSignednessAccelerated: VkBool32 + integerDotProduct32BitUnsignedAccelerated: VkBool32 + integerDotProduct32BitSignedAccelerated: VkBool32 + integerDotProduct32BitMixedSignednessAccelerated: VkBool32 + integerDotProduct64BitUnsignedAccelerated: VkBool32 + integerDotProduct64BitSignedAccelerated: VkBool32 + integerDotProduct64BitMixedSignednessAccelerated: VkBool32 + integerDotProductAccumulatingSaturating8BitUnsignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating8BitSignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated: VkBool32 + integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated: VkBool32 + integerDotProductAccumulatingSaturating16BitUnsignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating16BitSignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated: VkBool32 + integerDotProductAccumulatingSaturating32BitUnsignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating32BitSignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated: VkBool32 + integerDotProductAccumulatingSaturating64BitUnsignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating64BitSignedAccelerated: VkBool32 + integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated: VkBool32 + storageTexelBufferOffsetAlignmentBytes: VkDeviceSize + storageTexelBufferOffsetSingleTexelAlignment: VkBool32 + uniformTexelBufferOffsetAlignmentBytes: VkDeviceSize + uniformTexelBufferOffsetSingleTexelAlignment: VkBool32 + maxBufferSize: VkDeviceSize + + +@dataclass +class VkPhysicalDeviceVulkan13Features: + robustImageAccess: VkBool32 + inlineUniformBlock: VkBool32 + descriptorBindingInlineUniformBlockUpdateAfterBind: VkBool32 + pipelineCreationCacheControl: VkBool32 + privateData: VkBool32 + shaderDemoteToHelperInvocation: VkBool32 + shaderTerminateInvocation: VkBool32 + subgroupSizeControl: VkBool32 + computeFullSubgroups: VkBool32 + synchronization2: VkBool32 + textureCompressionASTC_HDR: VkBool32 + shaderZeroInitializeWorkgroupMemory: VkBool32 + dynamicRendering: VkBool32 + shaderIntegerDotProduct: VkBool32 + maintenance4: VkBool32 + + +@dataclass +class VkPhysicalDeviceVulkan14Properties: + lineSubPixelPrecisionBits: uint32_t + maxVertexAttribDivisor: uint32_t + supportsNonZeroFirstInstance: VkBool32 + maxPushDescriptors: uint32_t + dynamicRenderingLocalReadDepthStencilAttachments: VkBool32 + dynamicRenderingLocalReadMultisampledAttachments: VkBool32 + earlyFragmentMultisampleCoverageAfterSampleCounting: VkBool32 + earlyFragmentSampleMaskTestBeforeSampleCounting: VkBool32 + depthStencilSwizzleOneSupport: VkBool32 + polygonModePointSize: VkBool32 + nonStrictSinglePixelWideLinesUseParallelogram: VkBool32 + nonStrictWideLinesUseParallelogram: VkBool32 + blockTexelViewCompatibleMultipleLayers: VkBool32 + maxCombinedImageSamplerDescriptorCount: uint32_t + fragmentShadingRateClampCombinerInputs: VkBool32 + defaultRobustnessStorageBuffers: VkPipelineRobustnessBufferBehavior + defaultRobustnessUniformBuffers: VkPipelineRobustnessBufferBehavior + defaultRobustnessVertexInputs: VkPipelineRobustnessBufferBehavior + defaultRobustnessImages: VkPipelineRobustnessBufferBehavior + copySrcLayoutCount: uint32_t + pCopySrcLayouts: List[VkImageLayout] + copyDstLayoutCount: uint32_t + pCopyDstLayouts: List[VkImageLayout] + optimalTilingLayoutUUID: uint8_t + identicalMemoryTypeRequirements: VkBool32 + + +@dataclass +class VkPhysicalDeviceVulkan14Features: + globalPriorityQuery: VkBool32 + shaderSubgroupRotate: VkBool32 + shaderSubgroupRotateClustered: VkBool32 + shaderFloatControls2: VkBool32 + shaderExpectAssume: VkBool32 + rectangularLines: VkBool32 + bresenhamLines: VkBool32 + smoothLines: VkBool32 + stippledRectangularLines: VkBool32 + stippledBresenhamLines: VkBool32 + stippledSmoothLines: VkBool32 + vertexAttributeInstanceRateDivisor: VkBool32 + vertexAttributeInstanceRateZeroDivisor: VkBool32 + indexTypeUint8: VkBool32 + dynamicRenderingLocalRead: VkBool32 + maintenance5: VkBool32 + maintenance6: VkBool32 + pipelineProtectedAccess: VkBool32 + pipelineRobustness: VkBool32 + hostImageCopy: VkBool32 + # pushDescriptor: bool + + +@dataclass +class VkPhysicalDeviceDriverProperties: + driverID: VkDriverId + driverName: str + driverInfo: str + conformanceVersion: ConformanceVersion + +# Defining alias for structures +VkPhysicalDeviceLineRasterizationFeaturesEXT = VkPhysicalDeviceLineRasterizationFeatures +VkPhysicalDeviceLineRasterizationFeaturesKHR = VkPhysicalDeviceLineRasterizationFeatures +VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR = VkPhysicalDeviceShaderIntegerDotProductFeatures +VkPhysicalDevice8BitStorageFeaturesKHR = VkPhysicalDevice8BitStorageFeatures +VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR = VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures +VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR = VkPhysicalDeviceVertexAttributeDivisorFeatures +VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT = VkPhysicalDeviceVertexAttributeDivisorFeatures +VkPhysicalDeviceIndexTypeUint8FeaturesKHR = VkPhysicalDeviceIndexTypeUint8Features +VkPhysicalDeviceIndexTypeUint8FeaturesEXT = VkPhysicalDeviceIndexTypeUint8Features +VkPhysicalDeviceVariablePointerFeatures = VkPhysicalDeviceVariablePointersFeatures +VkPhysicalDeviceVariablePointersFeaturesKHR = VkPhysicalDeviceVariablePointersFeatures +VkPhysicalDeviceVariablePointerFeaturesKHR = VkPhysicalDeviceVariablePointersFeatures +VkPhysicalDeviceFloat16Int8FeaturesKHR = VkPhysicalDeviceShaderFloat16Int8Features +VkPhysicalDeviceShaderFloat16Int8FeaturesKHR = VkPhysicalDeviceShaderFloat16Int8Features +VkPhysicalDeviceFloatControlsPropertiesKHR = VkPhysicalDeviceFloatControlsProperties +VkPhysicalDeviceShaderDrawParametersFeatures = VkPhysicalDeviceShaderDrawParameterFeatures +VkPhysicalDeviceDriverPropertiesKHR = VkPhysicalDeviceDriverProperties + +# Defining dependency of structures on extensions +VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING = { + "extensions": { + "VK_KHR_variable_pointers": [ + { "VkPhysicalDeviceVariablePointerFeaturesKHR": "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES" }, + { "VkPhysicalDeviceVariablePointersFeaturesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES"}, + ], + "VK_KHR_shader_float16_int8": [ + { "VkPhysicalDeviceShaderFloat16Int8FeaturesKHR": "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES" }, + {"VkPhysicalDeviceFloat16Int8FeaturesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES"}, + ], + "VK_EXT_image_2d_view_of_3d" : [ + {"VkPhysicalDeviceImage2DViewOf3DFeaturesEXT" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT"}, + ], + "VK_EXT_custom_border_color" : [ + {"VkPhysicalDeviceCustomBorderColorFeaturesEXT" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT"}, + ], + "VK_EXT_primitive_topology_list_restart": [ + {"VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT"}, + ], + "VK_EXT_provoking_vertex" : [ + {"VkPhysicalDeviceProvokingVertexFeaturesEXT" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT"}, + ], + "VK_KHR_index_type_uint8" : [ + {"VkPhysicalDeviceIndexTypeUint8FeaturesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES"}, + ], + "VK_EXT_index_type_uint8" : [ + {"VkPhysicalDeviceIndexTypeUint8FeaturesEXT" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES"}, + ], + "VK_KHR_vertex_attribute_divisor" : [ + {"VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES"}, + ], + "VK_EXT_vertex_attribute_divisor" : [ + {"VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES"}, + ], + "VK_EXT_transform_feedback" : [ + {"VkPhysicalDeviceTransformFeedbackFeaturesEXT" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT"}, + ], + "VK_KHR_shader_subgroup_uniform_control_flow" : [ + {"VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR"}, + ], + "VK_KHR_shader_subgroup_extended_types" : [ + {"VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES"}, + ], + "VK_KHR_8bit_storage" : [ + {"VkPhysicalDevice8BitStorageFeaturesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES"}, + ], + "VK_KHR_shader_integer_dot_product" : [ + {"VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES"}, + ], + "VK_IMG_relaxed_line_rasterization" : [ + {"VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG"}, + ], + "VK_KHR_line_rasterization" : [ + {"VkPhysicalDeviceLineRasterizationFeaturesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES"}, + ], + "VK_EXT_line_rasterization" : [ + {"VkPhysicalDeviceLineRasterizationFeaturesEXT" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES"}, + ], + "VK_EXT_primitives_generated_query" : [ + {"VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT"}, + ], + "VK_KHR_shader_float_controls" : [ + {"VkPhysicalDeviceFloatControlsPropertiesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES"}, + ], + "VK_KHR_driver_properties" : [ + {"VkPhysicalDeviceDriverPropertiesKHR" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES"}, + ] + } +} + +# Defining dependency of structures on vulkan cores +VULKAN_CORES_AND_STRUCTS_MAPPING = { + "versions" : { + "Core11" : [ + {"VkPhysicalDeviceVulkan11Properties" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES"}, + {"VkPhysicalDeviceVulkan11Features" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES"}, + ], + "Core12" : [ + {"VkPhysicalDeviceVulkan12Properties" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES"}, + {"VkPhysicalDeviceVulkan12Features" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES"}, + ], + "Core13" : [ + {"VkPhysicalDeviceVulkan13Properties" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES"}, + {"VkPhysicalDeviceVulkan13Features" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES"}, + ], + "Core14" : [ + {"VkPhysicalDeviceVulkan14Properties" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_PROPERTIES"}, + {"VkPhysicalDeviceVulkan14Features" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES"}, + ] + } +} + +# Defining map for list type members mapped to its size +LIST_TYPE_FIELD_AND_SIZE_MAPPING = { + "pCopySrcLayouts": "copySrcLayoutCount", + "pCopyDstLayouts": "copyDstLayoutCount", + "memoryTypes": "memoryTypeCount", + "memoryHeaps": "memoryHeapCount", +} + +# Defining dependency of structures on vulkan api version +VULKAN_VERSIONS_AND_STRUCTS_MAPPING = { + "VK_VERSION_1_0" : [ + {"VkPhysicalDeviceProperties" : "" }, + {"VkPhysicalDeviceFeatures" : ""}, + {"VkPhysicalDeviceMemoryProperties" : ""}, + ], + "VK_VERSION_1_1" : [ + {"VkPhysicalDeviceSubgroupProperties" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES"}, + {"VkPhysicalDevicePointClippingProperties" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES"}, + {"VkPhysicalDeviceMultiviewProperties" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES"}, + {"VkPhysicalDeviceIDProperties" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES"}, + {"VkPhysicalDeviceMaintenance3Properties" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES"}, + {"VkPhysicalDeviceMultiviewFeatures" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES"}, + {"VkPhysicalDeviceVariablePointersFeatures" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES"}, + {"VkPhysicalDeviceProtectedMemoryFeatures" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES"}, + {"VkPhysicalDeviceSamplerYcbcrConversionFeatures" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES"}, + {"VkPhysicalDeviceShaderDrawParameterFeatures" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES"}, + {"VkPhysicalDevice16BitStorageFeatures" : "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES"}, + ] +} + +# List of structures that are not dependent on extensions +EXTENSION_INDEPENDENT_STRUCTS = [ + VkPhysicalDeviceProperties, + VkPhysicalDeviceFeatures, + VkPhysicalDeviceMemoryProperties, + VkPhysicalDeviceSubgroupProperties, + VkPhysicalDevicePointClippingProperties, + VkPhysicalDeviceMultiviewProperties, + VkPhysicalDeviceIDProperties, + VkPhysicalDeviceMaintenance3Properties, + VkPhysicalDevice16BitStorageFeatures, + VkPhysicalDeviceMultiviewFeatures, + VkPhysicalDeviceVariablePointersFeatures, + VkPhysicalDeviceProtectedMemoryFeatures, + VkPhysicalDeviceSamplerYcbcrConversionFeatures, + VkPhysicalDeviceShaderDrawParameterFeatures, +] + +# List of all the structures for vkjson +ALL_STRUCTS = [ + VkPhysicalDeviceFloatControlsPropertiesKHR, + VkPhysicalDeviceProperties, + VkPhysicalDeviceMemoryProperties, + VkPhysicalDeviceSubgroupProperties, + VkPhysicalDevicePointClippingProperties, + VkPhysicalDeviceMultiviewProperties, + VkPhysicalDeviceIDProperties, + VkPhysicalDeviceMaintenance3Properties, + VkPhysicalDeviceSparseProperties, + VkImageFormatProperties, + VkQueueFamilyProperties, + VkExtensionProperties, + VkLayerProperties, + VkFormatProperties, + VkPhysicalDeviceVariablePointerFeaturesKHR, + VkPhysicalDeviceVariablePointersFeaturesKHR, + VkPhysicalDeviceShaderFloat16Int8FeaturesKHR, + VkPhysicalDeviceFloat16Int8FeaturesKHR, + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT, + VkPhysicalDeviceCustomBorderColorFeaturesEXT, + VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT, + VkPhysicalDeviceProvokingVertexFeaturesEXT, + VkPhysicalDeviceIndexTypeUint8FeaturesKHR, + VkPhysicalDeviceIndexTypeUint8FeaturesEXT, + VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR, + VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT, + VkPhysicalDeviceTransformFeedbackFeaturesEXT, + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR, + VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR, + VkPhysicalDevice8BitStorageFeaturesKHR, + VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR, + VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG, + VkPhysicalDeviceLineRasterizationFeaturesKHR, + VkPhysicalDeviceLineRasterizationFeaturesEXT, + VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT, + VkPhysicalDevice16BitStorageFeatures, + VkPhysicalDeviceMultiviewFeatures, + VkPhysicalDeviceProtectedMemoryFeatures, + VkPhysicalDeviceSamplerYcbcrConversionFeatures, + VkPhysicalDeviceShaderDrawParameterFeatures, + VkPhysicalDeviceLimits, + VkPhysicalDeviceFeatures, + VkPhysicalDeviceVulkan11Properties, + VkPhysicalDeviceVulkan11Features, + VkPhysicalDeviceVulkan12Properties, + VkPhysicalDeviceVulkan12Features, + VkPhysicalDeviceVulkan13Properties, + VkPhysicalDeviceVulkan13Features, + VkPhysicalDeviceVulkan14Properties, + VkPhysicalDeviceVulkan14Features, + VkPhysicalDeviceDriverProperties, +] diff --git a/vulkan/scripts/vkjson_generator.py b/vulkan/scripts/vkjson_generator.py new file mode 100644 index 0000000000..7dc55d9703 --- /dev/null +++ b/vulkan/scripts/vkjson_generator.py @@ -0,0 +1,1882 @@ +#!/usr/bin/env python3 +# +# Copyright 2025 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generates the vkjson files. +""" +import dataclasses +import os +import re +from typing import get_origin + +import generator_common as gencom +import vk as VK + +dataclass_field = dataclasses.field + + +COPYRIGHT_WARNINGS = """/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015-2016 The Khronos Group Inc. +// Copyright (c) 2015-2016 Valve Corporation +// Copyright (c) 2015-2016 LunarG, Inc. +// Copyright (c) 2015-2016 Google, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +/////////////////////////////////////////////////////////////////////////////// +""" + + +def get_copyright_warnings(): + return COPYRIGHT_WARNINGS + + +def get_vkjson_struct_name(extension_name): + """Gets the corresponding structure name from a Vulkan extension name. + Example: "VK_KHR_shader_float16_int8" → "VkJsonKHRShaderFloat16Int8" + """ + prefix_map = { + "VK_KHR": "VkJsonKHR", + "VK_EXT": "VkJsonExt", + "VK_IMG": "VkJsonIMG" + } + + for prefix, replacement in prefix_map.items(): + if extension_name.startswith(prefix): + struct_name = replacement + extension_name[len(prefix):] + break + else: + struct_name = f"VkJsonExt{extension_name}" + + # Convert underscores to camel case + # Example: "VK_KHR_shader_float16_int8" → "VkJsonKHRShaderFloat16Int8" + struct_name = re.sub(r"_(.)", lambda m: m.group(1).upper(), struct_name) + + return struct_name + + +def get_vkjson_struct_variable_name(extension_name): + """Gets corresponding instance name from a Vulkan extension name. + Example: "VK_KHR_shader_float16_int8" → "khr_shader_float16_int8" + """ + prefix_map = { + "VK_KHR_": "khr_", + "VK_EXT_": "ext_", + "VK_IMG_": "img_" + } + + for prefix, replacement in prefix_map.items(): + if extension_name.startswith(prefix): + return replacement + extension_name[len(prefix):] + + return extension_name.lower() # Default case if no known prefix matches + + +def get_struct_name(struct_name): + """Gets corresponding instance name + Example: "VkPhysicalDeviceShaderFloat16Int8FeaturesKHR" → "shader_float16_int8_features_khr" + """ + # Remove "VkPhysicalDevice" prefix and any of the known suffixes + base_name = struct_name.removeprefix("VkPhysicalDevice").removesuffix("KHR").removesuffix("EXT").removesuffix("IMG") + + # Convert CamelCase to snake_case + # Example: "ShaderFloat16Int8Features" → "shader_float16_int8_features" + variable_name = re.sub(r"(?<!^)(?=[A-Z])", "_", base_name).lower() + + # Fix special cases + variable_name = variable_name.replace("2_d_", "_2d_").replace("3_d_", "_3d_") + + # Add back the correct suffix if it was removed + suffix_map = {"KHR": "_khr", "EXT": "_ext", "IMG": "_img"} + for suffix, replacement in suffix_map.items(): + if struct_name.endswith(suffix): + variable_name += replacement + break + + # Handle specific exceptions + special_cases = { + "8_bit_storage_features_khr": "bit8_storage_features_khr", + "memory_properties": "memory", + "16_bit_storage_features": "bit16_storage_features", + "i_d_properties": "id_properties" + } + + return special_cases.get(variable_name, variable_name) + + +def generate_extension_struct_definition(f): + """Generates struct definition code for extension based structs + Example: + struct VkJsonKHRShaderFloatControls { + VkJsonKHRShaderFloatControls() { + reported = false; + memset(&float_controls_properties_khr, 0, + sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)); + } + bool reported; + VkPhysicalDeviceFloatControlsPropertiesKHR float_controls_properties_khr; + }; + """ + vkJson_entries = [] + + for extension_name, struct_list in VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"].items(): + vkjson_struct_name = get_vkjson_struct_name(extension_name) + vkjson_struct_variable_name = get_vkjson_struct_variable_name(extension_name) + vkJson_entries.append(f"{vkjson_struct_name} {vkjson_struct_variable_name}") + + struct_entries = [] + + f.write(f"struct {vkjson_struct_name} {{\n") + f.write(f" {vkjson_struct_name}() {{\n") + f.write(" reported = false;\n") + + for struct_map in struct_list: + for struct_name, _ in struct_map.items(): + variable_name = get_struct_name(struct_name) + f.write(f" memset(&{variable_name}, 0, sizeof({struct_name}));\n") + struct_entries.append(f"{struct_name} {variable_name}") + + f.write(" }\n") # End of constructor + f.write(" bool reported;\n") + + for entry in struct_entries: + f.write(f" {entry};\n") + + f.write("};\n\n") # End of struct + + return vkJson_entries + + +def generate_vk_core_struct_definition(f): + """Generates struct definition code for vulkan cores + Example: + struct VkJsonCore11 { + VkPhysicalDeviceVulkan11Properties properties; + VkPhysicalDeviceVulkan11Features features; + }; + """ + vkJson_core_entries = [] + + for version, items in VK.VULKAN_CORES_AND_STRUCTS_MAPPING["versions"].items(): + struct_name = f"VkJson{version}" + vkJson_core_entries.append(f"{struct_name} {version.lower()}") + + f.write(f"struct {struct_name} {{\n") + + for item in items: + for struct_type, _ in item.items(): + field_name = "properties" if "Properties" in struct_type else "features" + f.write(f" {struct_type} {field_name};\n") + + f.write("};\n\n") + + return vkJson_core_entries + + +def generate_memset_statements(f): + """Generates memset statements for all independent Vulkan structs and core Vulkan versions. + This initializes struct instances to zero before use. + + Example: + memset(&properties, 0, sizeof(VkPhysicalDeviceProperties)); + VkPhysicalDeviceProperties properties; + """ + entries = [] + + # Process independent structs + for dataclass_type in VK.EXTENSION_INDEPENDENT_STRUCTS: + class_name = dataclass_type.__name__ + variable_name = get_struct_name(class_name) + f.write(f"memset(&{variable_name}, 0, sizeof({class_name}));\n") + entries.append(f"{class_name} {variable_name}") + + # Process vulkan core structs + for version in VK.VULKAN_CORES_AND_STRUCTS_MAPPING["versions"]: + struct_name = f"VkJson{version}" + f.write(f"memset(&{version.lower()}, 0, sizeof({struct_name}));\n") + + return entries + + +def gen_h(): + """Generates vkjson.h file. + """ + genfile = os.path.join(os.path.dirname(__file__), + "..", "vkjson", "vkjson.h") + + with open(genfile, "w") as f: + f.write(f'{get_copyright_warnings()}\n') + + f.write("""\ +#ifndef VKJSON_H_ +#define VKJSON_H_ + +#include <string.h> +#include <vulkan/vulkan.h> + +#include <map> +#include <string> +#include <vector> + +#ifdef WIN32 +#undef min +#undef max +#endif + +/* + * This file is autogenerated by vkjson_generator.py. Do not edit directly. + */ +struct VkJsonLayer { + VkLayerProperties properties; + std::vector<VkExtensionProperties> extensions; +}; + +\n""") + + vkjson_extension_structs = generate_extension_struct_definition(f) + vkjson_core_structs = generate_vk_core_struct_definition(f) + + f.write("""\ +struct VkJsonDevice { + VkJsonDevice() {""") + + feature_property_structs = generate_memset_statements(f) + + f.write("""\ + }\n""") + for struct_entries in (vkjson_extension_structs, vkjson_core_structs, feature_property_structs): + for entry in struct_entries: + f.write(entry + ";\n") + + f.write("""\ + std::vector<VkQueueFamilyProperties> queues; + std::vector<VkExtensionProperties> extensions; + std::vector<VkLayerProperties> layers; + std::map<VkFormat, VkFormatProperties> formats; + std::map<VkExternalFenceHandleTypeFlagBits, VkExternalFenceProperties> + external_fence_properties; + std::map<VkExternalSemaphoreHandleTypeFlagBits, VkExternalSemaphoreProperties> + external_semaphore_properties; +}; + +struct VkJsonDeviceGroup { + VkJsonDeviceGroup() { + memset(&properties, 0, sizeof(VkPhysicalDeviceGroupProperties)); + } + VkPhysicalDeviceGroupProperties properties; + std::vector<uint32_t> device_inds; +}; + +struct VkJsonInstance { + VkJsonInstance() : api_version(0) {} + uint32_t api_version; + std::vector<VkJsonLayer> layers; + std::vector<VkExtensionProperties> extensions; + std::vector<VkJsonDevice> devices; + std::vector<VkJsonDeviceGroup> device_groups; +}; + +VkJsonInstance VkJsonGetInstance(); +std::string VkJsonInstanceToJson(const VkJsonInstance& instance); +bool VkJsonInstanceFromJson(const std::string& json, + VkJsonInstance* instance, + std::string* errors); + +VkJsonDevice VkJsonGetDevice(VkPhysicalDevice device); +std::string VkJsonDeviceToJson(const VkJsonDevice& device); +bool VkJsonDeviceFromJson(const std::string& json, + VkJsonDevice* device, + std::string* errors); + +std::string VkJsonImageFormatPropertiesToJson( + const VkImageFormatProperties& properties); +bool VkJsonImageFormatPropertiesFromJson(const std::string& json, + VkImageFormatProperties* properties, + std::string* errors); + +// Backward-compatibility aliases +typedef VkJsonDevice VkJsonAllProperties; +inline VkJsonAllProperties VkJsonGetAllProperties( + VkPhysicalDevice physicalDevice) { + return VkJsonGetDevice(physicalDevice); +} +inline std::string VkJsonAllPropertiesToJson( + const VkJsonAllProperties& properties) { + return VkJsonDeviceToJson(properties); +} +inline bool VkJsonAllPropertiesFromJson(const std::string& json, + VkJsonAllProperties* properties, + std::string* errors) { + return VkJsonDeviceFromJson(json, properties, errors); +} + +#endif // VKJSON_H_""") + + f.close() + gencom.run_clang_format(genfile) + + +def generate_extension_struct_template(): + """Generates templates for extensions + Example: + template <typename Visitor> + inline bool Iterate(Visitor* visitor, VkJsonKHRVariablePointers* structs) { + return visitor->Visit("variablePointerFeaturesKHR", + &structs->variable_pointer_features_khr) && + visitor->Visit("variablePointersFeaturesKHR", + &structs->variable_pointers_features_khr); + } + """ + template_code = [] + + for extension, struct_mappings in VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"].items(): + struct_type = get_vkjson_struct_name(extension) + + template_code.append(f"template <typename Visitor>") + template_code.append(f"inline bool Iterate(Visitor* visitor, {struct_type}* structs) {{") + template_code.append(" return ") + + visitor_calls = [] + for struct_map in struct_mappings: + for struct_name in struct_map: + json_field_name = struct_name.replace("VkPhysicalDevice", "") + json_field_name = json_field_name[0].lower() + json_field_name[1:] + + # Special case renaming + if json_field_name == "8BitStorageFeaturesKHR": + json_field_name = "bit8StorageFeaturesKHR" + + visitor_calls.append( + f'visitor->Visit("{json_field_name}", &structs->{get_struct_name(struct_name)})' + ) + + template_code.append(" &&\n ".join(visitor_calls) + ";") + template_code.append("}\n") + + return "\n".join(template_code) + + +def generate_core_template(): + """Generates templates for vulkan cores. + template <typename Visitor> + inline bool Iterate(Visitor* visitor, VkJsonCore11* core) { + return visitor->Visit("properties", &core->properties) && + visitor->Visit("features", &core->features); + } + """ + template_code = [] + + for version, struct_list in VK.VULKAN_CORES_AND_STRUCTS_MAPPING["versions"].items(): + struct_type = f"VkJson{version}" + + template_code.append(f"template <typename Visitor>") + template_code.append(f"inline bool Iterate(Visitor* visitor, {struct_type}* core) {{") + template_code.append(" return") + + visitor_calls = [] + for struct_map in struct_list: + for struct_name in struct_map: + member_name = "properties" if "Properties" in struct_name else "features" + visitor_calls.append(f'visitor->Visit("{member_name}", &core->{member_name})') + + template_code.append(" &&\n ".join(visitor_calls) + ";") + template_code.append("}\n") + + return "\n".join(template_code) + + +def generate_struct_template(data_classes): + """Generates templates for all the structs + template <typename Visitor> + inline bool Iterate(Visitor* visitor, + VkPhysicalDevicePointClippingProperties* properties) { + return visitor->Visit("pointClippingBehavior", + &properties->pointClippingBehavior); + } + """ + template_code = [] + processed_classes = set() # Track processed class names + + for dataclass_type in data_classes: + struct_name = dataclass_type.__name__ + + if struct_name in processed_classes: + continue # Skip already processed struct + processed_classes.add(struct_name) + + struct_fields = dataclasses.fields(dataclass_type) + template_code.append("template <typename Visitor>") + + # Determine the correct variable name based on the struct type + struct_var = "properties" if "Properties" in struct_name else "features" if "Features" in struct_name else "limits" if "Limits" in struct_name else None + + if not struct_var: + continue # Skip structs that don't match expected patterns + + template_code.append(f"inline bool Iterate(Visitor* visitor, {struct_name}* {struct_var}) {{") + template_code.append(f"return\n") + + visitor_calls = [] + for struct_field in struct_fields: + field_name = struct_field.name + field_type = struct_field.type + + if get_origin(field_type) is list: + # Handle list types (VisitArray) + size_field_name = VK.LIST_TYPE_FIELD_AND_SIZE_MAPPING[field_name] + visitor_calls.append(f'visitor->VisitArray("{field_name}", {struct_var}->{size_field_name}, &{struct_var}->{field_name})') + else: + # Handle other types (Visit) + visitor_calls.append(f'visitor->Visit("{field_name}", &{struct_var}->{field_name})') + + template_code.append(" &&\n ".join(visitor_calls) + ";") + template_code.append("}\n\n") + + return "\n".join(template_code) + + +def emit_struct_visits_by_vk_version(f, version): + """Emits visitor calls for Vulkan version structs + """ + for struct_map in VK.VULKAN_VERSIONS_AND_STRUCTS_MAPPING[version]: + for struct_name, _ in struct_map.items(): + struct_var = get_struct_name(struct_name) + # Converts struct_var from snake_case (e.g., point_clipping_properties) + # to camelCase (e.g., pointClippingProperties) for struct_display_name. + struct_display_name = re.sub(r"_([a-z])", lambda match: match.group(1).upper(), struct_var) + f.write(f'visitor->Visit("{struct_display_name}", &device->{struct_var}) &&\n') + + +def gen_cc(): + """Generates vkjson.cc file. + """ + genfile = os.path.join(os.path.dirname(__file__), + "..", "vkjson", "vkjson.cc") + + with open(genfile, "w") as f: + + f.write(get_copyright_warnings()) + f.write("\n") + + f.write("""\ +#include "vkjson.h" + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include <json/json.h> + +#include <algorithm> +#include <cinttypes> +#include <cmath> +#include <cstdio> +#include <limits> +#include <memory> +#include <sstream> +#include <type_traits> +#include <utility> + +/* + * This file is autogenerated by vkjson_generator.py. Do not edit directly. + */ +namespace { + +/* + * Annotation to tell clang that we intend to fall through from one case to + * another in a switch. Sourced from android-base/macros.h. + */ +#define FALLTHROUGH_INTENDED [[clang::fallthrough]] + +inline bool IsIntegral(double value) { +#if defined(ANDROID) + // Android NDK doesn't provide std::trunc yet + return trunc(value) == value; +#else + return std::trunc(value) == value; +#endif +} + +// Floating point fields of Vulkan structure use single precision. The string +// output of max double value in c++ will be larger than Java double's infinity +// value. Below fake double max/min values are only to serve the safe json text +// parsing in between C++ and Java, because Java json library simply cannot +// handle infinity. +static const double SAFE_DOUBLE_MAX = 0.99 * std::numeric_limits<double>::max(); +static const double SAFE_DOUBLE_MIN = -SAFE_DOUBLE_MAX; + +template <typename T> struct EnumTraits; +template <> struct EnumTraits<VkPhysicalDeviceType> { + static bool exist(uint32_t e) { + switch (e) { + case VK_PHYSICAL_DEVICE_TYPE_OTHER: + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + case VK_PHYSICAL_DEVICE_TYPE_CPU: + return true; + } + return false; + } +}; + +template <> struct EnumTraits<VkFormat> { + static bool exist(uint32_t e) { + switch (e) { + case VK_FORMAT_UNDEFINED: + case VK_FORMAT_R4G4_UNORM_PACK8: + case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + case VK_FORMAT_B4G4R4A4_UNORM_PACK16: + case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VK_FORMAT_B5G6R5_UNORM_PACK16: + case VK_FORMAT_R5G5B5A1_UNORM_PACK16: + case VK_FORMAT_B5G5R5A1_UNORM_PACK16: + case VK_FORMAT_A1R5G5B5_UNORM_PACK16: + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R8_SNORM: + case VK_FORMAT_R8_USCALED: + case VK_FORMAT_R8_SSCALED: + case VK_FORMAT_R8_UINT: + case VK_FORMAT_R8_SINT: + case VK_FORMAT_R8_SRGB: + case VK_FORMAT_R8G8_UNORM: + case VK_FORMAT_R8G8_SNORM: + case VK_FORMAT_R8G8_USCALED: + case VK_FORMAT_R8G8_SSCALED: + case VK_FORMAT_R8G8_UINT: + case VK_FORMAT_R8G8_SINT: + case VK_FORMAT_R8G8_SRGB: + case VK_FORMAT_R8G8B8_UNORM: + case VK_FORMAT_R8G8B8_SNORM: + case VK_FORMAT_R8G8B8_USCALED: + case VK_FORMAT_R8G8B8_SSCALED: + case VK_FORMAT_R8G8B8_UINT: + case VK_FORMAT_R8G8B8_SINT: + case VK_FORMAT_R8G8B8_SRGB: + case VK_FORMAT_B8G8R8_UNORM: + case VK_FORMAT_B8G8R8_SNORM: + case VK_FORMAT_B8G8R8_USCALED: + case VK_FORMAT_B8G8R8_SSCALED: + case VK_FORMAT_B8G8R8_UINT: + case VK_FORMAT_B8G8R8_SINT: + case VK_FORMAT_B8G8R8_SRGB: + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SNORM: + case VK_FORMAT_R8G8B8A8_USCALED: + case VK_FORMAT_R8G8B8A8_SSCALED: + case VK_FORMAT_R8G8B8A8_UINT: + case VK_FORMAT_R8G8B8A8_SINT: + case VK_FORMAT_R8G8B8A8_SRGB: + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SNORM: + case VK_FORMAT_B8G8R8A8_USCALED: + case VK_FORMAT_B8G8R8A8_SSCALED: + case VK_FORMAT_B8G8R8A8_UINT: + case VK_FORMAT_B8G8R8A8_SINT: + case VK_FORMAT_B8G8R8A8_SRGB: + case VK_FORMAT_A8B8G8R8_UNORM_PACK32: + case VK_FORMAT_A8B8G8R8_SNORM_PACK32: + case VK_FORMAT_A8B8G8R8_USCALED_PACK32: + case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: + case VK_FORMAT_A8B8G8R8_UINT_PACK32: + case VK_FORMAT_A8B8G8R8_SINT_PACK32: + case VK_FORMAT_A8B8G8R8_SRGB_PACK32: + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: + case VK_FORMAT_A2R10G10B10_SNORM_PACK32: + case VK_FORMAT_A2R10G10B10_USCALED_PACK32: + case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: + case VK_FORMAT_A2R10G10B10_UINT_PACK32: + case VK_FORMAT_A2R10G10B10_SINT_PACK32: + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: + case VK_FORMAT_A2B10G10R10_SNORM_PACK32: + case VK_FORMAT_A2B10G10R10_USCALED_PACK32: + case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: + case VK_FORMAT_A2B10G10R10_UINT_PACK32: + case VK_FORMAT_A2B10G10R10_SINT_PACK32: + case VK_FORMAT_R16_UNORM: + case VK_FORMAT_R16_SNORM: + case VK_FORMAT_R16_USCALED: + case VK_FORMAT_R16_SSCALED: + case VK_FORMAT_R16_UINT: + case VK_FORMAT_R16_SINT: + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R16G16_UNORM: + case VK_FORMAT_R16G16_SNORM: + case VK_FORMAT_R16G16_USCALED: + case VK_FORMAT_R16G16_SSCALED: + case VK_FORMAT_R16G16_UINT: + case VK_FORMAT_R16G16_SINT: + case VK_FORMAT_R16G16_SFLOAT: + case VK_FORMAT_R16G16B16_UNORM: + case VK_FORMAT_R16G16B16_SNORM: + case VK_FORMAT_R16G16B16_USCALED: + case VK_FORMAT_R16G16B16_SSCALED: + case VK_FORMAT_R16G16B16_UINT: + case VK_FORMAT_R16G16B16_SINT: + case VK_FORMAT_R16G16B16_SFLOAT: + case VK_FORMAT_R16G16B16A16_UNORM: + case VK_FORMAT_R16G16B16A16_SNORM: + case VK_FORMAT_R16G16B16A16_USCALED: + case VK_FORMAT_R16G16B16A16_SSCALED: + case VK_FORMAT_R16G16B16A16_UINT: + case VK_FORMAT_R16G16B16A16_SINT: + case VK_FORMAT_R16G16B16A16_SFLOAT: + case VK_FORMAT_R32_UINT: + case VK_FORMAT_R32_SINT: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_R32G32_UINT: + case VK_FORMAT_R32G32_SINT: + case VK_FORMAT_R32G32_SFLOAT: + case VK_FORMAT_R32G32B32_UINT: + case VK_FORMAT_R32G32B32_SINT: + case VK_FORMAT_R32G32B32_SFLOAT: + case VK_FORMAT_R32G32B32A32_UINT: + case VK_FORMAT_R32G32B32A32_SINT: + case VK_FORMAT_R32G32B32A32_SFLOAT: + case VK_FORMAT_R64_UINT: + case VK_FORMAT_R64_SINT: + case VK_FORMAT_R64_SFLOAT: + case VK_FORMAT_R64G64_UINT: + case VK_FORMAT_R64G64_SINT: + case VK_FORMAT_R64G64_SFLOAT: + case VK_FORMAT_R64G64B64_UINT: + case VK_FORMAT_R64G64B64_SINT: + case VK_FORMAT_R64G64B64_SFLOAT: + case VK_FORMAT_R64G64B64A64_UINT: + case VK_FORMAT_R64G64B64A64_SINT: + case VK_FORMAT_R64G64B64A64_SFLOAT: + case VK_FORMAT_B10G11R11_UFLOAT_PACK32: + case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_S8_UINT: + case VK_FORMAT_D16_UNORM_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + case VK_FORMAT_BC1_RGB_UNORM_BLOCK: + case VK_FORMAT_BC1_RGB_SRGB_BLOCK: + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC2_SRGB_BLOCK: + case VK_FORMAT_BC3_UNORM_BLOCK: + case VK_FORMAT_BC3_SRGB_BLOCK: + case VK_FORMAT_BC4_UNORM_BLOCK: + case VK_FORMAT_BC4_SNORM_BLOCK: + case VK_FORMAT_BC5_UNORM_BLOCK: + case VK_FORMAT_BC5_SNORM_BLOCK: + case VK_FORMAT_BC6H_UFLOAT_BLOCK: + case VK_FORMAT_BC6H_SFLOAT_BLOCK: + case VK_FORMAT_BC7_UNORM_BLOCK: + case VK_FORMAT_BC7_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + case VK_FORMAT_EAC_R11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11_SNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: + case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: + case VK_FORMAT_G8B8G8R8_422_UNORM: + case VK_FORMAT_B8G8R8G8_422_UNORM: + case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: + case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: + case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: + case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: + case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: + case VK_FORMAT_R10X6_UNORM_PACK16: + case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: + case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: + case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: + case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: + case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: + case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: + case VK_FORMAT_R12X4_UNORM_PACK16: + case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: + case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: + case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: + case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: + case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: + case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: + case VK_FORMAT_G16B16G16R16_422_UNORM: + case VK_FORMAT_B16G16R16G16_422_UNORM: + case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: + case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: + case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: + case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: + case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: + case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: + case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: + case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: + case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: + case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: + case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: + case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: + case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: + case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT: + case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT: + case VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT: + case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT: + return true; + } + return false; + } +}; + +template <> +struct EnumTraits<VkPointClippingBehavior> { + static bool exist(uint32_t e) { + switch (e) { + case VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES: + case VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY: + return true; + } + return false; + } +}; + +template <> +struct EnumTraits<VkExternalFenceHandleTypeFlagBits> { + static bool exist(uint32_t e) { + switch (e) { + case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT: + case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT: + case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: + case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT: + return true; + } + return false; + } +}; + +template <> +struct EnumTraits<VkExternalSemaphoreHandleTypeFlagBits> { + static bool exist(uint32_t e) { + switch (e) { + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT: + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT: + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT: + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT: + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: + return true; + } + return false; + } +}; + +template <> +struct EnumTraits<VkDriverIdKHR> { + static bool exist(uint32_t e) { + switch (e) { + case VK_DRIVER_ID_AMD_PROPRIETARY: + case VK_DRIVER_ID_AMD_OPEN_SOURCE: + case VK_DRIVER_ID_MESA_RADV: + case VK_DRIVER_ID_NVIDIA_PROPRIETARY: + case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS: + case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA: + case VK_DRIVER_ID_IMAGINATION_PROPRIETARY: + case VK_DRIVER_ID_QUALCOMM_PROPRIETARY: + case VK_DRIVER_ID_ARM_PROPRIETARY: + case VK_DRIVER_ID_GOOGLE_SWIFTSHADER: + case VK_DRIVER_ID_GGP_PROPRIETARY: + case VK_DRIVER_ID_BROADCOM_PROPRIETARY: + case VK_DRIVER_ID_MESA_LLVMPIPE: + case VK_DRIVER_ID_MOLTENVK: + return true; + } + return false; + } +}; + +template <> +struct EnumTraits<VkShaderFloatControlsIndependence> { + static bool exist(uint32_t e) { + switch (e) { + case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY: + case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL: + case VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE: + return true; + } + return false; + } +}; + +template <> +struct EnumTraits<VkPipelineRobustnessBufferBehavior> { + static bool exist(uint32_t e) { + switch (e) { + case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT: + case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED: + case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS: + case VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2: + return true; + } + return false; + } +}; + +template <> +struct EnumTraits<VkPipelineRobustnessImageBehavior> { + static bool exist(uint32_t e) { + switch (e) { + case VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT: + case VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED: + case VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS: + case VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2: + return true; + } + return false; + } +}; + +template <> +struct EnumTraits<VkImageLayout> { + static bool exist(uint32_t e) { + switch (e) { + case VK_IMAGE_LAYOUT_UNDEFINED: + case VK_IMAGE_LAYOUT_GENERAL: + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + case VK_IMAGE_LAYOUT_PREINITIALIZED: + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL: + case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: + case VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR: + case VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR: + case VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR: + case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR: + case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT: + case VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR: +#ifdef VK_ENABLE_BETA_EXTENSIONS + case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR: +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + case VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR: +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR: +#endif + case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT: + return true; + } + return false; + } +}; + +// VkSparseImageFormatProperties + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkExtent3D* extents) { + return + visitor->Visit("width", &extents->width) && + visitor->Visit("height", &extents->height) && + visitor->Visit("depth", &extents->depth); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkConformanceVersionKHR* version) { + return visitor->Visit("major", &version->major) && + visitor->Visit("minor", &version->minor) && + visitor->Visit("subminor", &version->subminor) && + visitor->Visit("patch", &version->patch); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkMemoryType* type) { + return + visitor->Visit("propertyFlags", &type->propertyFlags) && + visitor->Visit("heapIndex", &type->heapIndex); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkMemoryHeap* heap) { + return + visitor->Visit("size", &heap->size) && + visitor->Visit("flags", &heap->flags); +}\n\n""") + + f.write(f"{generate_core_template()}\n\n{generate_extension_struct_template()}\n\n") + f.write(generate_struct_template(VK.ALL_STRUCTS)) + + f.write("""\ +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkExternalFenceProperties* properties) { + return visitor->Visit("exportFromImportedHandleTypes", + &properties->exportFromImportedHandleTypes) && + visitor->Visit("compatibleHandleTypes", + &properties->compatibleHandleTypes) && + visitor->Visit("externalFenceFeatures", + &properties->externalFenceFeatures); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkExternalSemaphoreProperties* properties) { + return visitor->Visit("exportFromImportedHandleTypes", + &properties->exportFromImportedHandleTypes) && + visitor->Visit("compatibleHandleTypes", + &properties->compatibleHandleTypes) && + visitor->Visit("externalSemaphoreFeatures", + &properties->externalSemaphoreFeatures); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonLayer* layer) { + return visitor->Visit("properties", &layer->properties) && + visitor->Visit("extensions", &layer->extensions); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonDeviceGroup* device_group) { + return visitor->Visit("devices", &device_group->device_inds) && + visitor->Visit("subsetAllocation", + &device_group->properties.subsetAllocation); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonDevice* device) { + bool ret = true; + switch (device->properties.apiVersion ^ + VK_API_VERSION_PATCH(device->properties.apiVersion)) { + case VK_API_VERSION_1_4: + ret &= visitor->Visit("core14", &device->core14); + FALLTHROUGH_INTENDED; + case VK_API_VERSION_1_3: + ret &= visitor->Visit("core13", &device->core13); + FALLTHROUGH_INTENDED; + case VK_API_VERSION_1_2: + ret &= visitor->Visit("core11", &device->core11); + ret &= visitor->Visit("core12", &device->core12); + FALLTHROUGH_INTENDED; + case VK_API_VERSION_1_1: + ret &=\n""") + + emit_struct_visits_by_vk_version(f, "VK_VERSION_1_1") + + f.write("""\ + visitor->Visit("externalFenceProperties", + &device->external_fence_properties) && + visitor->Visit("externalSemaphoreProperties", + &device->external_semaphore_properties); + FALLTHROUGH_INTENDED; + case VK_API_VERSION_1_0: + ret &=\n""") + + emit_struct_visits_by_vk_version(f, "VK_VERSION_1_0") + + f.write("""\ + visitor->Visit("queues", &device->queues) && + visitor->Visit("extensions", &device->extensions) && + visitor->Visit("layers", &device->layers) && + visitor->Visit("formats", &device->formats);\n\n""") + + for extension_name, _ in VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"].items(): + struct_var = get_vkjson_struct_variable_name(extension_name) + f.write(f" if (device->{struct_var}.reported) {{\n") + f.write(f" ret &= visitor->Visit(\"{extension_name}\", &device->{struct_var});\n") + f.write(" }\n") + + f.write("""\ + } return ret; } + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonInstance* instance) { + bool ret = true; + switch (instance->api_version ^ VK_API_VERSION_PATCH(instance->api_version)) { + case VK_API_VERSION_1_4: + FALLTHROUGH_INTENDED; + case VK_API_VERSION_1_3: + FALLTHROUGH_INTENDED; + case VK_API_VERSION_1_2: + ret &= visitor->Visit("apiVersion", &instance->api_version); + FALLTHROUGH_INTENDED; + case VK_API_VERSION_1_1: + ret &= visitor->Visit("deviceGroups", &instance->device_groups); + FALLTHROUGH_INTENDED; + case VK_API_VERSION_1_0: + char depString[] = + "vkjson is deprecated, and will be replaced in a future release"; + ret &= visitor->Visit("layers", &instance->layers) && + visitor->Visit("extensions", &instance->extensions) && + visitor->Visit("devices", &instance->devices) && + visitor->Visit("_comment", &depString); + } + return ret; +} + +template <typename T> +using EnableForArithmetic = + typename std::enable_if<std::is_arithmetic<T>::value, void>::type; + +template <typename T> +using EnableForStruct = + typename std::enable_if<std::is_class<T>::value, void>::type; + +template <typename T> +using EnableForEnum = + typename std::enable_if<std::is_enum<T>::value, void>::type; + +template <typename T, typename = EnableForStruct<T>, typename = void> +Json::Value ToJsonValue(const T& value); + +template <typename T, typename = EnableForArithmetic<T>> +inline Json::Value ToJsonValue(const T& value) { + return Json::Value( + std::clamp(static_cast<double>(value), SAFE_DOUBLE_MIN, SAFE_DOUBLE_MAX)); +} + +inline Json::Value ToJsonValue(const uint64_t& value) { + char string[19] = {0}; // "0x" + 16 digits + terminal \\0 + snprintf(string, sizeof(string), "0x%016" PRIx64, value); + return Json::Value(string); +} + +template <typename T, typename = EnableForEnum<T>, typename = void, + typename = void> +inline Json::Value ToJsonValue(const T& value) { + return Json::Value(static_cast<double>(value)); +} + +template <typename T> +inline Json::Value ArrayToJsonValue(uint32_t count, const T* values) { + Json::Value array(Json::arrayValue); + for (unsigned int i = 0; i < count; ++i) array.append(ToJsonValue(values[i])); + return array; +} + +template <typename T, size_t N> +inline Json::Value ToJsonValue(const T (&value)[N]) { + return ArrayToJsonValue(N, value); +} + +template <size_t N> +inline Json::Value ToJsonValue(const char (&value)[N]) { + assert(strlen(value) < N); + return Json::Value(value); +} + +template <typename T> +inline Json::Value ToJsonValue(const std::vector<T>& value) { + assert(value.size() <= std::numeric_limits<uint32_t>::max()); + return ArrayToJsonValue(static_cast<uint32_t>(value.size()), value.data()); +} + +template <typename F, typename S> +inline Json::Value ToJsonValue(const std::pair<F, S>& value) { + Json::Value array(Json::arrayValue); + array.append(ToJsonValue(value.first)); + array.append(ToJsonValue(value.second)); + return array; +} + +template <typename F, typename S> +inline Json::Value ToJsonValue(const std::map<F, S>& value) { + Json::Value array(Json::arrayValue); + for (auto& kv : value) array.append(ToJsonValue(kv)); + return array; +} + +class JsonWriterVisitor { + public: + JsonWriterVisitor() : object_(Json::objectValue) {} + + ~JsonWriterVisitor() {} + + template <typename T> bool Visit(const char* key, const T* value) { + object_[key] = ToJsonValue(*value); + return true; + } + + template <typename T, uint32_t N> + bool VisitArray(const char* key, uint32_t count, const T (*value)[N]) { + assert(count <= N); + object_[key] = ArrayToJsonValue(count, *value); + return true; + } + + template <typename T> + bool VisitArray(const char* key, uint32_t count, const T *value) { + object_[key] = ArrayToJsonValue(count, *value); + return true; + } + + Json::Value get_object() const { return object_; } + + private: + Json::Value object_; +}; + +template <typename Visitor, typename T> +inline void VisitForWrite(Visitor* visitor, const T& t) { + Iterate(visitor, const_cast<T*>(&t)); +} + +template <typename T, typename /*= EnableForStruct<T>*/, typename /*= void*/> +Json::Value ToJsonValue(const T& value) { + JsonWriterVisitor visitor; + VisitForWrite(&visitor, value); + return visitor.get_object(); +} + +template <typename T, typename = EnableForStruct<T>> +bool AsValue(Json::Value* json_value, T* t); + +inline bool AsValue(Json::Value* json_value, int32_t* value) { + if (json_value->type() != Json::realValue) return false; + double d = json_value->asDouble(); + if (!IsIntegral(d) || + d < static_cast<double>(std::numeric_limits<int32_t>::min()) || + d > static_cast<double>(std::numeric_limits<int32_t>::max())) + return false; + *value = static_cast<int32_t>(d); + return true; +} + +inline bool AsValue(Json::Value* json_value, uint64_t* value) { + if (json_value->type() != Json::stringValue) return false; + int result = + std::sscanf(json_value->asString().c_str(), "0x%016" PRIx64, value); + return result == 1; +} + +inline bool AsValue(Json::Value* json_value, uint32_t* value) { + if (json_value->type() != Json::realValue) return false; + double d = json_value->asDouble(); + if (!IsIntegral(d) || d < 0.0 || + d > static_cast<double>(std::numeric_limits<uint32_t>::max())) + return false; + *value = static_cast<uint32_t>(d); + return true; +} + +inline bool AsValue(Json::Value* json_value, uint8_t* value) { + uint32_t value32 = 0; + AsValue(json_value, &value32); + if (value32 > std::numeric_limits<uint8_t>::max()) + return false; + *value = static_cast<uint8_t>(value32); + return true; +} + +inline bool AsValue(Json::Value* json_value, float* value) { + if (json_value->type() != Json::realValue) return false; + *value = static_cast<float>(json_value->asDouble()); + return true; +} + +inline bool AsValue(Json::Value* json_value, VkImageLayout* t) { + uint32_t value = 0; + if (!AsValue(json_value, &value)) + return false; + if (!EnumTraits<VkImageLayout>::exist(value)) return false; + *t = static_cast<VkImageLayout>(value); + return true; +} + +template <typename T> +inline bool AsArray(Json::Value* json_value, uint32_t count, T* values) { + if (json_value->type() != Json::arrayValue || json_value->size() != count) + return false; + for (uint32_t i = 0; i < count; ++i) { + if (!AsValue(&(*json_value)[i], values + i)) return false; + } + return true; +} + +template <typename T, size_t N> +inline bool AsValue(Json::Value* json_value, T (*value)[N]) { + return AsArray(json_value, N, *value); +} + +template <size_t N> +inline bool AsValue(Json::Value* json_value, char (*value)[N]) { + if (json_value->type() != Json::stringValue) return false; + size_t len = json_value->asString().length(); + if (len >= N) + return false; + memcpy(*value, json_value->asString().c_str(), len); + memset(*value + len, 0, N-len); + return true; +} + +template <typename T, typename = EnableForEnum<T>, typename = void> +inline bool AsValue(Json::Value* json_value, T* t) { + uint32_t value = 0; + if (!AsValue(json_value, &value)) + return false; + if (!EnumTraits<T>::exist(value)) return false; + *t = static_cast<T>(value); + return true; +} + +template <typename T> +inline bool AsValue(Json::Value* json_value, std::vector<T>* value) { + if (json_value->type() != Json::arrayValue) return false; + int size = json_value->size(); + value->resize(size); + return AsArray(json_value, size, value->data()); +} + +template <typename F, typename S> +inline bool AsValue(Json::Value* json_value, std::pair<F, S>* value) { + if (json_value->type() != Json::arrayValue || json_value->size() != 2) + return false; + return AsValue(&(*json_value)[0], &value->first) && + AsValue(&(*json_value)[1], &value->second); +} + +template <typename F, typename S> +inline bool AsValue(Json::Value* json_value, std::map<F, S>* value) { + if (json_value->type() != Json::arrayValue) return false; + int size = json_value->size(); + for (int i = 0; i < size; ++i) { + std::pair<F, S> elem; + if (!AsValue(&(*json_value)[i], &elem)) return false; + if (!value->insert(elem).second) + return false; + } + return true; +} + +template <typename T> +bool ReadValue(Json::Value* object, const char* key, T* value, + std::string* errors) { + Json::Value json_value = (*object)[key]; + if (!json_value) { + if (errors) + *errors = std::string(key) + " missing."; + return false; + } + if (AsValue(&json_value, value)) return true; + if (errors) + *errors = std::string("Wrong type for ") + std::string(key) + "."; + return false; +} + +template <typename Visitor, typename T> +inline bool VisitForRead(Visitor* visitor, T* t) { + return Iterate(visitor, t); +} + +class JsonReaderVisitor { + public: + JsonReaderVisitor(Json::Value* object, std::string* errors) + : object_(object), errors_(errors) {} + + template <typename T> bool Visit(const char* key, T* value) const { + return ReadValue(object_, key, value, errors_); + } + + template <typename T, uint32_t N> + bool VisitArray(const char* key, uint32_t count, T (*value)[N]) { + if (count > N) + return false; + Json::Value json_value = (*object_)[key]; + if (!json_value) { + if (errors_) + *errors_ = std::string(key) + " missing."; + return false; + } + if (AsArray(&json_value, count, *value)) return true; + if (errors_) + *errors_ = std::string("Wrong type for ") + std::string(key) + "."; + return false; + } + + template <typename T> + bool VisitArray(const char* key, uint32_t count, T *value) { + Json::Value json_value = (*object_)[key]; + if (!json_value) { + if (errors_) + *errors_ = std::string(key) + " missing."; + return false; + } + if (AsArray(&json_value, count, *value)) return true; + if (errors_) + *errors_ = std::string("Wrong type for ") + std::string(key) + "."; + return false; + } + + + private: + Json::Value* object_; + std::string* errors_; +}; + +template <typename T, typename /*= EnableForStruct<T>*/> +bool AsValue(Json::Value* json_value, T* t) { + if (json_value->type() != Json::objectValue) return false; + JsonReaderVisitor visitor(json_value, nullptr); + return VisitForRead(&visitor, t); +} + + +template <typename T> std::string VkTypeToJson(const T& t) { + JsonWriterVisitor visitor; + VisitForWrite(&visitor, t); + return visitor.get_object().toStyledString(); +} + +template <typename T> bool VkTypeFromJson(const std::string& json, + T* t, + std::string* errors) { + *t = T(); + Json::Value object(Json::objectValue); + Json::CharReaderBuilder builder; + builder["collectComments"] = false; + std::unique_ptr<Json::CharReader> reader(builder.newCharReader()); + if (!reader->parse(json.data(), json.data() + json.size(), &object, errors)) { + return false; + } + return AsValue(&object, t); +} + +} // anonymous namespace + +std::string VkJsonInstanceToJson(const VkJsonInstance& instance) { + return VkTypeToJson(instance); +} + +bool VkJsonInstanceFromJson(const std::string& json, + VkJsonInstance* instance, + std::string* errors) { + return VkTypeFromJson(json, instance, errors); +} + +std::string VkJsonDeviceToJson(const VkJsonDevice& device) { + return VkTypeToJson(device); +} + +bool VkJsonDeviceFromJson(const std::string& json, + VkJsonDevice* device, + std::string* errors) { + return VkTypeFromJson(json, device, errors); +}; + +std::string VkJsonImageFormatPropertiesToJson( + const VkImageFormatProperties& properties) { + return VkTypeToJson(properties); +} + +bool VkJsonImageFormatPropertiesFromJson(const std::string& json, + VkImageFormatProperties* properties, + std::string* errors) { + return VkTypeFromJson(json, properties, errors); +}; +""") + f.close() + gencom.run_clang_format(genfile) + + +def generate_vk_core_structs_init_code(version): + """Generates code to initialize properties and features + for structs based on its vulkan API version dependency. + """ + properties_code, features_code = [], [] + + for item in VK.VULKAN_CORES_AND_STRUCTS_MAPPING["versions"].get(version, []): + for struct_name, struct_type in item.items(): + version_lower = version.lower() + + if "Properties" in struct_name: + properties_code.extend([ + f"device.{version_lower}.properties.sType = {struct_type};", + f"device.{version_lower}.properties.pNext = properties.pNext;", + f"properties.pNext = &device.{version_lower}.properties;\n\n" + ]) + + elif "Features" in struct_name: + features_code.extend([ + f"device.{version_lower}.features.sType = {struct_type};", + f"device.{version_lower}.features.pNext = features.pNext;", + f"features.pNext = &device.{version_lower}.features;\n\n" + ]) + + return "\n".join(properties_code), "\n".join(features_code) + + +def generate_vk_extension_structs_init_code(mapping, struct_category, next_pointer): + """Generates Vulkan struct initialization code for given struct category (Properties/Features) + based on its extension dependency. + """ + generated_code = [] + + for extension, struct_mappings in mapping.items(): + struct_var_name = get_vkjson_struct_variable_name(extension) + extension_code = [ + f" if (HasExtension(\"{extension}\", device.extensions)) {{", + f" device.{struct_var_name}.reported = true;" + ] + + struct_count = 0 + for struct_mapping in struct_mappings: + for struct_name, struct_type in struct_mapping.items(): + if struct_category in struct_name: + struct_count += 1 + struct_instance = get_struct_name(struct_name) + extension_code.extend([ + f" device.{struct_var_name}.{struct_instance}.sType = {struct_type};", + f" device.{struct_var_name}.{struct_instance}.pNext = {next_pointer}.pNext;", + f" {next_pointer}.pNext = &device.{struct_var_name}.{struct_instance};" + ]) + + extension_code.append(" }\n") + + if struct_count > 0: + generated_code.extend(extension_code) + + return "\n".join(generated_code) + + +def generate_vk_version_structs_initialization(version_data, struct_type_keyword, next_pointer): + """Generates Vulkan struct initialization code for given struct category (Properties/Features) + of vulkan api version s. + """ + struct_initialization_code = [] + + for struct_mapping in version_data: + for struct_name, struct_type in struct_mapping.items(): + if struct_type_keyword in struct_name: + struct_variable = get_struct_name(struct_name) + struct_initialization_code.extend([ + f"device.{struct_variable}.sType = {struct_type};", + f"device.{struct_variable}.pNext = {next_pointer}.pNext;", + f"{next_pointer}.pNext = &device.{struct_variable};\n" + ]) + + return "\n".join(struct_initialization_code) + + +def gen_instance_cc(): + """Generates vkjson_instance.cc file. + """ + genfile = os.path.join(os.path.dirname(__file__), + "..", "vkjson", "vkjson_instance.cc") + + with open(genfile, "w") as f: + f.write(get_copyright_warnings()) + f.write("\n") + + f.write("""\ +#ifndef VK_PROTOTYPES +#define VK_PROTOTYPES +#endif + +#include "vkjson.h" + +#include <algorithm> +#include <utility> + +/* + * This file is autogenerated by vkjson_generator.py. Do not edit directly. + */ +namespace { + +bool EnumerateExtensions(const char* layer_name, + std::vector<VkExtensionProperties>* extensions) { + VkResult result; + uint32_t count = 0; + result = vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr); + if (result != VK_SUCCESS) + return false; + extensions->resize(count); + result = vkEnumerateInstanceExtensionProperties(layer_name, &count, + extensions->data()); + if (result != VK_SUCCESS) + return false; + return true; +} + +bool HasExtension(const char* extension_name, + const std::vector<VkExtensionProperties>& extensions) { + return std::find_if(extensions.cbegin(), extensions.cend(), + [extension_name](const VkExtensionProperties& extension) { + return strcmp(extension.extensionName, + extension_name) == 0; + }) != extensions.cend(); +} +} // anonymous namespace + +VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) { + VkJsonDevice device; + + uint32_t extension_count = 0; + vkEnumerateDeviceExtensionProperties(physical_device, nullptr, + &extension_count, nullptr); + if (extension_count > 0) { + device.extensions.resize(extension_count); + vkEnumerateDeviceExtensionProperties( + physical_device, nullptr, &extension_count, device.extensions.data()); + } + + uint32_t layer_count = 0; + vkEnumerateDeviceLayerProperties(physical_device, &layer_count, nullptr); + if (layer_count > 0) { + device.layers.resize(layer_count); + vkEnumerateDeviceLayerProperties(physical_device, &layer_count, + device.layers.data()); + } + + VkPhysicalDeviceProperties2 properties = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + nullptr, + {}, + };\n\n""") + + cc_code_properties = generate_vk_extension_structs_init_code( + VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"], "Properties", "properties" + ) + f.write(f'{cc_code_properties}\n') + + f.write("""\ + + vkGetPhysicalDeviceProperties2(physical_device, &properties); + device.properties = properties.properties; + + VkPhysicalDeviceFeatures2 features = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + nullptr, + {}, + };\n\n""") + + cc_code_features = generate_vk_extension_structs_init_code( + VK.VULKAN_EXTENSIONS_AND_STRUCTS_MAPPING["extensions"], "Features", "features" + ) + f.write(f'{cc_code_features}\n') + + f.write("""\ + + vkGetPhysicalDeviceFeatures2(physical_device, &features); + device.features = features.features; + + vkGetPhysicalDeviceMemoryProperties(physical_device, &device.memory); + + uint32_t queue_family_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, + nullptr); + if (queue_family_count > 0) { + device.queues.resize(queue_family_count); + vkGetPhysicalDeviceQueueFamilyProperties( + physical_device, &queue_family_count, device.queues.data()); + } + + VkFormatProperties format_properties = {}; + for (VkFormat format = VK_FORMAT_R4G4_UNORM_PACK8; + // TODO(http://b/171403054): avoid hard-coding last value in the + // contiguous range + format <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK; + format = static_cast<VkFormat>(format + 1)) { + vkGetPhysicalDeviceFormatProperties(physical_device, format, + &format_properties); + if (format_properties.linearTilingFeatures || + format_properties.optimalTilingFeatures || + format_properties.bufferFeatures) { + device.formats.insert(std::make_pair(format, format_properties)); + } + } + + if (device.properties.apiVersion >= VK_API_VERSION_1_1) { + for (VkFormat format = VK_FORMAT_G8B8G8R8_422_UNORM; + // TODO(http://b/171403054): avoid hard-coding last value in the + // contiguous range + format <= VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM; + format = static_cast<VkFormat>(format + 1)) { + vkGetPhysicalDeviceFormatProperties(physical_device, format, + &format_properties); + if (format_properties.linearTilingFeatures || + format_properties.optimalTilingFeatures || + format_properties.bufferFeatures) { + device.formats.insert(std::make_pair(format, format_properties)); + } + }\n\n""") + + # Vulkan version data for VK_VERSION_1_1 + vk_version_data = VK.VULKAN_VERSIONS_AND_STRUCTS_MAPPING["VK_VERSION_1_1"] + f.write(generate_vk_version_structs_initialization(vk_version_data, "Properties", "properties") + "\n") + + f.write("""\ + vkGetPhysicalDeviceProperties2(physical_device, &properties);\n\n""") + + features_initialization_code = generate_vk_version_structs_initialization(vk_version_data, "Features", "features") + f.write(features_initialization_code) + + f.write("""\ + + vkGetPhysicalDeviceFeatures2(physical_device, &features); + + VkPhysicalDeviceExternalFenceInfo external_fence_info = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, nullptr, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT}; + VkExternalFenceProperties external_fence_properties = {}; + + for (VkExternalFenceHandleTypeFlagBits handle_type = + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT; + handle_type <= VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT; + handle_type = + static_cast<VkExternalFenceHandleTypeFlagBits>(handle_type << 1)) { + external_fence_info.handleType = handle_type; + vkGetPhysicalDeviceExternalFenceProperties( + physical_device, &external_fence_info, &external_fence_properties); + if (external_fence_properties.exportFromImportedHandleTypes || + external_fence_properties.compatibleHandleTypes || + external_fence_properties.externalFenceFeatures) { + device.external_fence_properties.insert( + std::make_pair(handle_type, external_fence_properties)); + } + } + + VkPhysicalDeviceExternalSemaphoreInfo external_semaphore_info = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, nullptr, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT}; + VkExternalSemaphoreProperties external_semaphore_properties = {}; + + for (VkExternalSemaphoreHandleTypeFlagBits handle_type = + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT; + handle_type <= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; + handle_type = static_cast<VkExternalSemaphoreHandleTypeFlagBits>( + handle_type << 1)) { + external_semaphore_info.handleType = handle_type; + vkGetPhysicalDeviceExternalSemaphoreProperties( + physical_device, &external_semaphore_info, + &external_semaphore_properties); + if (external_semaphore_properties.exportFromImportedHandleTypes || + external_semaphore_properties.compatibleHandleTypes || + external_semaphore_properties.externalSemaphoreFeatures) { + device.external_semaphore_properties.insert( + std::make_pair(handle_type, external_semaphore_properties)); + } + } + } + + if (device.properties.apiVersion >= VK_API_VERSION_1_2) {\n""") + + cc_code_properties_11, cc_code_features_11 = generate_vk_core_structs_init_code("Core11") + cc_code_properties_12, cc_code_features_12 = generate_vk_core_structs_init_code("Core12") + cc_code_properties_13, cc_code_features_13 = generate_vk_core_structs_init_code("Core13") + cc_code_properties_14, cc_code_features_14 = generate_vk_core_structs_init_code("Core14") + + f.write(cc_code_properties_11) + f.write(cc_code_properties_12) + f.write(f"vkGetPhysicalDeviceProperties2(physical_device, &properties);\n\n") + f.write(cc_code_features_11) + f.write(cc_code_features_12) + f.write(f"vkGetPhysicalDeviceFeatures2(physical_device, &features);\n\n") + f.write("""\ + } + + if (device.properties.apiVersion >= VK_API_VERSION_1_3) {\n""") + f.write(cc_code_properties_13) + f.write(f"vkGetPhysicalDeviceProperties2(physical_device, &properties);\n\n") + f.write(cc_code_features_13) + f.write(f"vkGetPhysicalDeviceFeatures2(physical_device, &features);\n\n") + f.write("""\ + } + + if (device.properties.apiVersion >= VK_API_VERSION_1_4) {\n""") + f.write(cc_code_properties_14) + f.write(f"vkGetPhysicalDeviceProperties2(physical_device, &properties);\n\n") + f.write(cc_code_features_14) + f.write(f"vkGetPhysicalDeviceFeatures2(physical_device, &features);\n\n") + f.write("""\ + } + + return device; +} + +VkJsonInstance VkJsonGetInstance() { + VkJsonInstance instance; + VkResult result; + uint32_t count; + + count = 0; + result = vkEnumerateInstanceLayerProperties(&count, nullptr); + if (result != VK_SUCCESS) + return VkJsonInstance(); + if (count > 0) { + std::vector<VkLayerProperties> layers(count); + result = vkEnumerateInstanceLayerProperties(&count, layers.data()); + if (result != VK_SUCCESS) + return VkJsonInstance(); + instance.layers.reserve(count); + for (auto& layer : layers) { + instance.layers.push_back(VkJsonLayer{layer, std::vector<VkExtensionProperties>()}); + if (!EnumerateExtensions(layer.layerName, + &instance.layers.back().extensions)) + return VkJsonInstance(); + } + } + + if (!EnumerateExtensions(nullptr, &instance.extensions)) + return VkJsonInstance(); + + const VkApplicationInfo app_info = { + VK_STRUCTURE_TYPE_APPLICATION_INFO, + nullptr, + "vkjson_info", + 1, + "", + 0, + VK_API_VERSION_1_1, + }; + VkInstanceCreateInfo instance_info = { + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + nullptr, + 0, + &app_info, + 0, + nullptr, + 0, + nullptr, + }; + VkInstance vkinstance; + result = vkCreateInstance(&instance_info, nullptr, &vkinstance); + if (result != VK_SUCCESS) + return VkJsonInstance(); + + count = 0; + result = vkEnumeratePhysicalDevices(vkinstance, &count, nullptr); + if (result != VK_SUCCESS) { + vkDestroyInstance(vkinstance, nullptr); + return VkJsonInstance(); + } + + std::vector<VkPhysicalDevice> devices(count, VK_NULL_HANDLE); + result = vkEnumeratePhysicalDevices(vkinstance, &count, devices.data()); + if (result != VK_SUCCESS) { + vkDestroyInstance(vkinstance, nullptr); + return VkJsonInstance(); + } + + std::map<VkPhysicalDevice, uint32_t> device_map; + const uint32_t sz = devices.size(); + instance.devices.reserve(sz); + for (uint32_t i = 0; i < sz; ++i) { + device_map.insert(std::make_pair(devices[i], i)); + instance.devices.emplace_back(VkJsonGetDevice(devices[i])); + } + + result = vkEnumerateInstanceVersion(&instance.api_version); + if (result != VK_SUCCESS) { + vkDestroyInstance(vkinstance, nullptr); + return VkJsonInstance(); + } + + count = 0; + result = vkEnumeratePhysicalDeviceGroups(vkinstance, &count, nullptr); + if (result != VK_SUCCESS) { + vkDestroyInstance(vkinstance, nullptr); + return VkJsonInstance(); + } + + VkJsonDeviceGroup device_group; + std::vector<VkPhysicalDeviceGroupProperties> group_properties; + group_properties.resize(count); + for (auto& properties : group_properties) { + properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES; + properties.pNext = nullptr; + } + result = vkEnumeratePhysicalDeviceGroups(vkinstance, &count, + group_properties.data()); + if (result != VK_SUCCESS) { + vkDestroyInstance(vkinstance, nullptr); + return VkJsonInstance(); + } + for (auto properties : group_properties) { + device_group.properties = properties; + for (uint32_t i = 0; i < properties.physicalDeviceCount; ++i) { + device_group.device_inds.push_back( + device_map[properties.physicalDevices[i]]); + } + instance.device_groups.push_back(device_group); + } + + vkDestroyInstance(vkinstance, nullptr); + return instance; +} + +\n""") + + f.close() + gencom.run_clang_format(genfile)
\ No newline at end of file diff --git a/vulkan/tests/Android.bp b/vulkan/tests/Android.bp new file mode 100644 index 0000000000..db218c18ee --- /dev/null +++ b/vulkan/tests/Android.bp @@ -0,0 +1,57 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_native_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_native_license"], +} + +cc_test { + name: "libvulkan_test", + test_suites: ["general-tests"], + + srcs: [ + "libvulkan_test.cpp", + ], + + strip: { + none: true, + }, + + cflags: [ + "-DVK_USE_PLATFORM_ANDROID_KHR", + "-Wall", + "-Werror", + ], + + header_libs: [ + "hwvulkan_headers", + "libvulkanprivate_headers-testing", + "vulkan_headers", + ], + + cppflags: [ + "-Wno-c++98-compat-pedantic", + "-Wno-c99-extensions", + "-Wno-exit-time-destructors", + "-Wno-float-equal", + "-Wno-global-constructors", + "-Wno-zero-length-array", + ], + + shared_libs: [ + "libbase", + "libgraphicsenv", + "liblog", + "libmediandk", + "libvulkan", + ], + + static_libs: [ + "libgmock", + "libgtest", + "liblog", + ], + +} diff --git a/vulkan/tests/README.md b/vulkan/tests/README.md new file mode 100644 index 0000000000..3c9b66cee5 --- /dev/null +++ b/vulkan/tests/README.md @@ -0,0 +1,24 @@ +#libvulkan_test + +This binary contains the unit tests for testing libvulkan (The Vulkan Loader). + +These tests rely on the underlying GPU driver to be able to successfully create a valid +swapchain. These tests are design to run on an Android emulator to give us a consistent GPU +driver to test against. YMMV when running this on a physical device with an arbitrary GPU +driver. + +To run these tests run: +``` +atest libvulkan_test +``` + +If using an acloud device the full command list for the root of a freshly cloned repo would be: +``` +source build/envsetup.sh +lunch aosp_cf_x86_64_phone-trunk_staging-eng +m +acloud create --local-image +atest libvulkan_test +``` + + diff --git a/vulkan/tests/libvulkan_test.cpp b/vulkan/tests/libvulkan_test.cpp new file mode 100644 index 0000000000..7e4bfd8e80 --- /dev/null +++ b/vulkan/tests/libvulkan_test.cpp @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android/log.h> +#include <driver.h> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <media/NdkImageReader.h> +#include <vulkan/vulkan.h> + +#define LOGI(...) \ + __android_log_print(ANDROID_LOG_INFO, "libvulkan_test", __VA_ARGS__) +#define LOGE(...) \ + __android_log_print(ANDROID_LOG_ERROR, "libvulkan_test", __VA_ARGS__) + +#define VK_CHECK(result) ASSERT_EQ(VK_SUCCESS, result) + +namespace android { + +namespace libvulkantest { + +class AImageReaderVulkanSwapchainTest : public ::testing::Test { + public: + AImageReaderVulkanSwapchainTest() {} + + AImageReader* mReader = nullptr; + ANativeWindow* mWindow = nullptr; + VkInstance mVkInstance = VK_NULL_HANDLE; + VkPhysicalDevice mPhysicalDev = VK_NULL_HANDLE; + VkDevice mDevice = VK_NULL_HANDLE; + VkSurfaceKHR mSurface = VK_NULL_HANDLE; + VkQueue mPresentQueue = VK_NULL_HANDLE; + uint32_t mPresentQueueFamily = UINT32_MAX; + VkSwapchainKHR mSwapchain = VK_NULL_HANDLE; + + void SetUp() override {} + + void TearDown() override {} + + // ------------------------------------------------------ + // Helper methods + // ------------------------------------------------------ + + void createVulkanInstance(std::vector<const char*>& layers) { + const char* extensions[] = { + VK_KHR_SURFACE_EXTENSION_NAME, + VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, + VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, + }; + + VkApplicationInfo appInfo{}; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pApplicationName = "AImageReader Vulkan Swapchain Test"; + appInfo.applicationVersion = 1; + appInfo.pEngineName = "TestEngine"; + appInfo.engineVersion = 1; + appInfo.apiVersion = VK_API_VERSION_1_0; + + VkInstanceCreateInfo instInfo{}; + instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instInfo.pApplicationInfo = &appInfo; + instInfo.enabledExtensionCount = + sizeof(extensions) / sizeof(extensions[0]); + instInfo.ppEnabledExtensionNames = extensions; + instInfo.enabledLayerCount = layers.size(); + instInfo.ppEnabledLayerNames = layers.data(); + VkResult res = vkCreateInstance(&instInfo, nullptr, &mVkInstance); + VK_CHECK(res); + LOGE("Vulkan instance created"); + } + + void createAImageReader(int width, int height, int format, int maxImages) { + media_status_t status = + AImageReader_new(width, height, format, maxImages, &mReader); + ASSERT_EQ(AMEDIA_OK, status) << "Failed to create AImageReader"; + ASSERT_NE(nullptr, mReader) << "AImageReader is null"; + + // Optionally set a listener + AImageReader_ImageListener listener{}; + listener.context = this; + listener.onImageAvailable = + &AImageReaderVulkanSwapchainTest::onImageAvailable; + AImageReader_setImageListener(mReader, &listener); + + LOGI("AImageReader created with %dx%d, format=%d", width, height, + format); + } + + void getANativeWindowFromReader() { + ASSERT_NE(nullptr, mReader); + + media_status_t status = AImageReader_getWindow(mReader, &mWindow); + ASSERT_EQ(AMEDIA_OK, status) + << "Failed to get ANativeWindow from AImageReader"; + ASSERT_NE(nullptr, mWindow) << "ANativeWindow is null"; + LOGI("ANativeWindow obtained from AImageReader"); + } + + void createVulkanSurface() { + ASSERT_NE((VkInstance)VK_NULL_HANDLE, mVkInstance); + ASSERT_NE((ANativeWindow*)nullptr, mWindow); + + VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo{}; + surfaceCreateInfo.sType = + VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.window = mWindow; + + VkResult res = vkCreateAndroidSurfaceKHR( + mVkInstance, &surfaceCreateInfo, nullptr, &mSurface); + VK_CHECK(res); + LOGI("Vulkan surface created from ANativeWindow"); + } + + void pickPhysicalDeviceAndQueueFamily() { + ASSERT_NE((VkInstance)VK_NULL_HANDLE, mVkInstance); + + uint32_t deviceCount = 0; + vkEnumeratePhysicalDevices(mVkInstance, &deviceCount, nullptr); + ASSERT_GT(deviceCount, 0U) << "No Vulkan physical devices found!"; + + std::vector<VkPhysicalDevice> devices(deviceCount); + vkEnumeratePhysicalDevices(mVkInstance, &deviceCount, devices.data()); + + for (auto& dev : devices) { + uint32_t queueFamilyCount = 0; + vkGetPhysicalDeviceQueueFamilyProperties(dev, &queueFamilyCount, + nullptr); + std::vector<VkQueueFamilyProperties> queueProps(queueFamilyCount); + vkGetPhysicalDeviceQueueFamilyProperties(dev, &queueFamilyCount, + queueProps.data()); + + for (uint32_t i = 0; i < queueFamilyCount; i++) { + VkBool32 support = VK_FALSE; + vkGetPhysicalDeviceSurfaceSupportKHR(dev, i, mSurface, + &support); + if (support == VK_TRUE) { + // Found a queue family that can present + mPhysicalDev = dev; + mPresentQueueFamily = i; + + LOGI( + "Physical device found with queue family %u supporting " + "present", + i); + return; + } + } + } + + FAIL() + << "No physical device found that supports present to the surface!"; + } + + void createDeviceAndGetQueue(std::vector<const char*>& layers, + std::vector<const char*> inExtensions = {}) { + ASSERT_NE((void*)VK_NULL_HANDLE, mPhysicalDev); + ASSERT_NE(UINT32_MAX, mPresentQueueFamily); + + float queuePriority = 1.0f; + VkDeviceQueueCreateInfo queueInfo{}; + queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueInfo.queueFamilyIndex = mPresentQueueFamily; + queueInfo.queueCount = 1; + queueInfo.pQueuePriorities = &queuePriority; + + VkDeviceCreateInfo deviceInfo{}; + deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + deviceInfo.queueCreateInfoCount = 1; + deviceInfo.pQueueCreateInfos = &queueInfo; + deviceInfo.enabledLayerCount = layers.size(); + deviceInfo.ppEnabledLayerNames = layers.data(); + + std::vector<const char*> extensions = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME, + }; + for (auto extension : inExtensions) { + extensions.push_back(extension); + } + deviceInfo.enabledExtensionCount = extensions.size(); + deviceInfo.ppEnabledExtensionNames = extensions.data(); + + VkResult res = + vkCreateDevice(mPhysicalDev, &deviceInfo, nullptr, &mDevice); + VK_CHECK(res); + LOGI("Logical device created"); + + vkGetDeviceQueue(mDevice, mPresentQueueFamily, 0, &mPresentQueue); + ASSERT_NE((VkQueue)VK_NULL_HANDLE, mPresentQueue); + LOGI("Acquired present-capable queue"); + } + + void createSwapchain() { + ASSERT_NE((VkDevice)VK_NULL_HANDLE, mDevice); + ASSERT_NE((VkSurfaceKHR)VK_NULL_HANDLE, mSurface); + + VkSurfaceCapabilitiesKHR surfaceCaps{}; + VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + mPhysicalDev, mSurface, &surfaceCaps)); + + uint32_t formatCount = 0; + vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDev, mSurface, + &formatCount, nullptr); + ASSERT_GT(formatCount, 0U); + std::vector<VkSurfaceFormatKHR> formats(formatCount); + vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDev, mSurface, + &formatCount, formats.data()); + + VkSurfaceFormatKHR chosenFormat = formats[0]; + LOGI("Chosen surface format: %d", chosenFormat.format); + + uint32_t presentModeCount = 0; + vkGetPhysicalDeviceSurfacePresentModesKHR(mPhysicalDev, mSurface, + &presentModeCount, nullptr); + ASSERT_GT(presentModeCount, 0U); + std::vector<VkPresentModeKHR> presentModes(presentModeCount); + vkGetPhysicalDeviceSurfacePresentModesKHR( + mPhysicalDev, mSurface, &presentModeCount, presentModes.data()); + + VkPresentModeKHR chosenPresentMode = VK_PRESENT_MODE_FIFO_KHR; + for (auto mode : presentModes) { + if (mode == VK_PRESENT_MODE_FIFO_KHR) { + chosenPresentMode = mode; + break; + } + } + LOGI("Chosen present mode: %d", chosenPresentMode); + + VkExtent2D swapchainExtent{}; + if (surfaceCaps.currentExtent.width == 0xFFFFFFFF) { + swapchainExtent.width = 640; // fallback + swapchainExtent.height = 480; // fallback + } else { + swapchainExtent = surfaceCaps.currentExtent; + } + LOGI("Swapchain extent: %d x %d", swapchainExtent.width, + swapchainExtent.height); + + uint32_t desiredImageCount = surfaceCaps.minImageCount + 1; + if (surfaceCaps.maxImageCount > 0 && + desiredImageCount > surfaceCaps.maxImageCount) { + desiredImageCount = surfaceCaps.maxImageCount; + } + + VkSwapchainCreateInfoKHR swapchainInfo{}; + swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchainInfo.surface = mSurface; + swapchainInfo.minImageCount = desiredImageCount; + swapchainInfo.imageFormat = chosenFormat.format; + swapchainInfo.imageColorSpace = chosenFormat.colorSpace; + swapchainInfo.imageExtent = swapchainExtent; + swapchainInfo.imageArrayLayers = 1; + swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + swapchainInfo.preTransform = surfaceCaps.currentTransform; + swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; + swapchainInfo.presentMode = chosenPresentMode; + swapchainInfo.clipped = VK_TRUE; + swapchainInfo.oldSwapchain = VK_NULL_HANDLE; + + uint32_t queueFamilyIndices[] = {mPresentQueueFamily}; + swapchainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + swapchainInfo.queueFamilyIndexCount = 1; + swapchainInfo.pQueueFamilyIndices = queueFamilyIndices; + + VkResult res = + vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain); + if (res == VK_SUCCESS) { + LOGI("Swapchain created successfully"); + + uint32_t swapchainImageCount = 0; + vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount, + nullptr); + std::vector<VkImage> swapchainImages(swapchainImageCount); + vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount, + swapchainImages.data()); + + LOGI("Swapchain has %u images", swapchainImageCount); + } else { + LOGI("Swapchain creation failed"); + } + } + + // Image available callback (AImageReader) + static void onImageAvailable(void*, AImageReader* reader) { + LOGI("onImageAvailable callback triggered"); + AImage* image = nullptr; + media_status_t status = AImageReader_acquireLatestImage(reader, &image); + if (status != AMEDIA_OK || !image) { + LOGE("Failed to acquire latest image"); + return; + } + AImage_delete(image); + LOGI("Released acquired image"); + } + + void cleanUpSwapchainForTest() { + if (mSwapchain != VK_NULL_HANDLE) { + vkDestroySwapchainKHR(mDevice, mSwapchain, nullptr); + mSwapchain = VK_NULL_HANDLE; + } + if (mDevice != VK_NULL_HANDLE) { + vkDestroyDevice(mDevice, nullptr); + mDevice = VK_NULL_HANDLE; + } + if (mSurface != VK_NULL_HANDLE) { + vkDestroySurfaceKHR(mVkInstance, mSurface, nullptr); + mSurface = VK_NULL_HANDLE; + } + if (mVkInstance != VK_NULL_HANDLE) { + vkDestroyInstance(mVkInstance, nullptr); + mVkInstance = VK_NULL_HANDLE; + } + if (mReader) { + // AImageReader_delete(mReader); + mReader = nullptr; + } + // Note: The ANativeWindow from AImageReader is implicitly + // managed by the reader, so we don't explicitly delete it. + mWindow = nullptr; + } + + void buildSwapchianForTest(std::vector<const char*>& instanceLayers, + std::vector<const char*>& deviceLayers) { + createVulkanInstance(instanceLayers); + + // the "atest libvulkan_test" command will execute this test as a binary + // (not apk) on the device. Consequently we can't render to the screen + // and need to work around this by using AImageReader* + createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3); + getANativeWindowFromReader(); + createVulkanSurface(); + pickPhysicalDeviceAndQueueFamily(); + + createDeviceAndGetQueue(deviceLayers); + createSwapchain(); + } +}; + +TEST_F(AImageReaderVulkanSwapchainTest, TestHelperMethods) { + // Verify that the basic plumbing/helper functions of these tests is + // working. This doesn't directly test any of the layer code. It only + // verifies that we can successfully create a swapchain with an AImageReader + + std::vector<const char*> instanceLayers; + std::vector<const char*> deviceLayers; + buildSwapchianForTest(deviceLayers, instanceLayers); + + ASSERT_NE(mVkInstance, (VkInstance)VK_NULL_HANDLE); + ASSERT_NE(mPhysicalDev, (VkPhysicalDevice)VK_NULL_HANDLE); + ASSERT_NE(mDevice, (VkDevice)VK_NULL_HANDLE); + ASSERT_NE(mSurface, (VkSurfaceKHR)VK_NULL_HANDLE); + ASSERT_NE(mSwapchain, (VkSwapchainKHR)VK_NULL_HANDLE); + cleanUpSwapchainForTest(); +} + +// Passing state in these tests requires global state. Wrap each test in an +// anonymous namespace to prevent conflicting names. +namespace { + +VKAPI_ATTR VkResult VKAPI_CALL hookedGetPhysicalDeviceImageFormatProperties2KHR( + VkPhysicalDevice, + const VkPhysicalDeviceImageFormatInfo2*, + VkImageFormatProperties2*) { + return VK_ERROR_SURFACE_LOST_KHR; +} + +static PFN_vkGetSwapchainGrallocUsage2ANDROID + pfnNextGetSwapchainGrallocUsage2ANDROID = nullptr; + +static bool g_grallocCalled = false; + +VKAPI_ATTR VkResult VKAPI_CALL hookGetSwapchainGrallocUsage2ANDROID( + VkDevice device, + VkFormat format, + VkImageUsageFlags imageUsage, + VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, + uint64_t* grallocConsumerUsage, + uint64_t* grallocProducerUsage) { + g_grallocCalled = true; + if (pfnNextGetSwapchainGrallocUsage2ANDROID) { + return pfnNextGetSwapchainGrallocUsage2ANDROID( + device, format, imageUsage, swapchainImageUsage, + grallocConsumerUsage, grallocProducerUsage); + } + + return VK_ERROR_INITIALIZATION_FAILED; +} + +TEST_F(AImageReaderVulkanSwapchainTest, getProducerUsageFallbackTest1) { + // BUG: 379230826 + // Verify that getProducerUsage falls back to + // GetSwapchainGrallocUsage*ANDROID if GPDIFP2 fails + std::vector<const char*> instanceLayers = {}; + std::vector<const char*> deviceLayers = {}; + createVulkanInstance(instanceLayers); + + createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3); + getANativeWindowFromReader(); + createVulkanSurface(); + pickPhysicalDeviceAndQueueFamily(); + + createDeviceAndGetQueue(deviceLayers); + auto& pdev = vulkan::driver::GetData(mDevice).driver_physical_device; + auto& pdevDispatchTable = vulkan::driver::GetData(pdev).driver; + auto& deviceDispatchTable = vulkan::driver::GetData(mDevice).driver; + + ASSERT_NE(deviceDispatchTable.GetSwapchainGrallocUsage2ANDROID, nullptr); + + pdevDispatchTable.GetPhysicalDeviceImageFormatProperties2 = + hookedGetPhysicalDeviceImageFormatProperties2KHR; + deviceDispatchTable.GetSwapchainGrallocUsage2ANDROID = + hookGetSwapchainGrallocUsage2ANDROID; + + ASSERT_FALSE(g_grallocCalled); + + createSwapchain(); + + ASSERT_TRUE(g_grallocCalled); + + ASSERT_NE(mVkInstance, (VkInstance)VK_NULL_HANDLE); + ASSERT_NE(mPhysicalDev, (VkPhysicalDevice)VK_NULL_HANDLE); + ASSERT_NE(mDevice, (VkDevice)VK_NULL_HANDLE); + ASSERT_NE(mSurface, (VkSurfaceKHR)VK_NULL_HANDLE); + cleanUpSwapchainForTest(); +} + +} // namespace + +// Passing state in these tests requires global state. Wrap each test in an +// anonymous namespace to prevent conflicting names. +namespace { + +static bool g_returnNotSupportedOnce = true; + +VKAPI_ATTR VkResult VKAPI_CALL +Hook_GetPhysicalDeviceImageFormatProperties2_NotSupportedOnce( + VkPhysicalDevice /*physicalDevice*/, + const VkPhysicalDeviceImageFormatInfo2* /*pImageFormatInfo*/, + VkImageFormatProperties2* /*pImageFormatProperties*/) { + if (g_returnNotSupportedOnce) { + g_returnNotSupportedOnce = false; + return VK_ERROR_FORMAT_NOT_SUPPORTED; + } + return VK_SUCCESS; +} + +TEST_F(AImageReaderVulkanSwapchainTest, SurfaceFormats2KHR_IgnoreNotSupported) { + // BUG: 357903074 + // Verify that vkGetPhysicalDeviceSurfaceFormats2KHR properly + // ignores VK_ERROR_FORMAT_NOT_SUPPORTED and continues enumerating formats. + std::vector<const char*> instanceLayers; + createVulkanInstance(instanceLayers); + createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3); + getANativeWindowFromReader(); + createVulkanSurface(); + pickPhysicalDeviceAndQueueFamily(); + + auto& pdevDispatchTable = vulkan::driver::GetData(mPhysicalDev).driver; + pdevDispatchTable.GetPhysicalDeviceImageFormatProperties2 = + Hook_GetPhysicalDeviceImageFormatProperties2_NotSupportedOnce; + + PFN_vkGetPhysicalDeviceSurfaceFormats2KHR + pfnGetPhysicalDeviceSurfaceFormats2KHR = + reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormats2KHR>( + vkGetInstanceProcAddr(mVkInstance, + "vkGetPhysicalDeviceSurfaceFormats2KHR")); + ASSERT_NE(nullptr, pfnGetPhysicalDeviceSurfaceFormats2KHR) + << "Could not get pointer to vkGetPhysicalDeviceSurfaceFormats2KHR"; + + VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo2{}; + surfaceInfo2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR; + surfaceInfo2.pNext = nullptr; + surfaceInfo2.surface = mSurface; + + uint32_t formatCount = 0; + VkResult res = pfnGetPhysicalDeviceSurfaceFormats2KHR( + mPhysicalDev, &surfaceInfo2, &formatCount, nullptr); + + // If the loader never tries a second format, it might fail or 0-out the + // formatCount. The patch ensures it continues to the next format rather + // than bailing out on the first NOT_SUPPORTED. + ASSERT_EQ(VK_SUCCESS, res) + << "vkGetPhysicalDeviceSurfaceFormats2KHR failed unexpectedly"; + ASSERT_GT(formatCount, 0U) + << "No surface formats found; the loader may have bailed early."; + + std::vector<VkSurfaceFormat2KHR> formats(formatCount); + for (auto& f : formats) { + f.sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR; + f.pNext = nullptr; + } + res = pfnGetPhysicalDeviceSurfaceFormats2KHR(mPhysicalDev, &surfaceInfo2, + &formatCount, formats.data()); + ASSERT_EQ(VK_SUCCESS, res) << "Failed to retrieve surface formats"; + + LOGI( + "SurfaceFormats2KHR_IgnoreNotSupported test: found %u formats after " + "ignoring NOT_SUPPORTED", + formatCount); + + cleanUpSwapchainForTest(); +} + +} // namespace + +namespace { + +TEST_F(AImageReaderVulkanSwapchainTest, MutableFormatSwapchainTest) { + // Test swapchain with mutable format extension + std::vector<const char*> instanceLayers; + std::vector<const char*> deviceLayers; + std::vector<const char*> deviceExtensions = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME, + VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, + VK_KHR_MAINTENANCE2_EXTENSION_NAME, + VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME}; + + createVulkanInstance(instanceLayers); + createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3); + getANativeWindowFromReader(); + createVulkanSurface(); + pickPhysicalDeviceAndQueueFamily(); + createDeviceAndGetQueue(deviceLayers, deviceExtensions); + + ASSERT_NE((VkDevice)VK_NULL_HANDLE, mDevice); + ASSERT_NE((VkSurfaceKHR)VK_NULL_HANDLE, mSurface); + + VkSurfaceCapabilitiesKHR surfaceCaps{}; + VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface, + &surfaceCaps)); + + uint32_t formatCount = 0; + vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDev, mSurface, &formatCount, + nullptr); + ASSERT_GT(formatCount, 0U); + std::vector<VkSurfaceFormatKHR> formats(formatCount); + vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDev, mSurface, &formatCount, + formats.data()); + + VkFormat viewFormats[2] = {formats[0].format, formats[0].format}; + if (formatCount > 1) { + viewFormats[1] = formats[1].format; + } + + VkImageFormatListCreateInfoKHR formatList{}; + formatList.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR; + formatList.viewFormatCount = 2; + formatList.pViewFormats = viewFormats; + + VkSwapchainCreateInfoKHR swapchainInfo{}; + swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchainInfo.pNext = &formatList; + swapchainInfo.surface = mSurface; + swapchainInfo.minImageCount = surfaceCaps.minImageCount + 1; + swapchainInfo.imageFormat = formats[0].format; + swapchainInfo.imageColorSpace = formats[0].colorSpace; + swapchainInfo.imageExtent = surfaceCaps.currentExtent; + swapchainInfo.imageArrayLayers = 1; + swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + swapchainInfo.preTransform = surfaceCaps.currentTransform; + swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; + swapchainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; + swapchainInfo.clipped = VK_TRUE; + + swapchainInfo.flags = VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR; + + uint32_t queueFamilyIndices[] = {mPresentQueueFamily}; + swapchainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + swapchainInfo.queueFamilyIndexCount = 1; + swapchainInfo.pQueueFamilyIndices = queueFamilyIndices; + + VkResult res = + vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain); + if (res == VK_SUCCESS) { + LOGI("Mutable format swapchain created successfully"); + + uint32_t imageCount = 0; + vkGetSwapchainImagesKHR(mDevice, mSwapchain, &imageCount, nullptr); + ASSERT_GT(imageCount, 0U); + } else { + LOGI( + "Mutable format swapchain creation failed (extension may not be " + "supported)"); + } + + cleanUpSwapchainForTest(); +} + +} // namespace + +} // namespace libvulkantest + +} // namespace android diff --git a/vulkan/vkjson/vkjson.cc b/vulkan/vkjson/vkjson.cc index 3cb94050af..531a623e90 100644 --- a/vulkan/vkjson/vkjson.cc +++ b/vulkan/vkjson/vkjson.cc @@ -38,6 +38,12 @@ namespace { +/* + * Annotation to tell clang that we intend to fall through from one case to + * another in a switch. Sourced from android-base/macros.h. + */ +#define FALLTHROUGH_INTENDED [[clang::fallthrough]] + inline bool IsIntegral(double value) { #if defined(ANDROID) // Android NDK doesn't provide std::trunc yet @@ -50,13 +56,15 @@ inline bool IsIntegral(double value) { // Floating point fields of Vulkan structure use single precision. The string // output of max double value in c++ will be larger than Java double's infinity // value. Below fake double max/min values are only to serve the safe json text -// parsing in between C++ and Java, becasue Java json library simply cannot +// parsing in between C++ and Java, because Java json library simply cannot // handle infinity. static const double SAFE_DOUBLE_MAX = 0.99 * std::numeric_limits<double>::max(); static const double SAFE_DOUBLE_MIN = -SAFE_DOUBLE_MAX; -template <typename T> struct EnumTraits; -template <> struct EnumTraits<VkPhysicalDeviceType> { +template <typename T> +struct EnumTraits; +template <> +struct EnumTraits<VkPhysicalDeviceType> { static bool exist(uint32_t e) { switch (e) { case VK_PHYSICAL_DEVICE_TYPE_OTHER: @@ -70,7 +78,8 @@ template <> struct EnumTraits<VkPhysicalDeviceType> { } }; -template <> struct EnumTraits<VkFormat> { +template <> +struct EnumTraits<VkFormat> { static bool exist(uint32_t e) { switch (e) { case VK_FORMAT_UNDEFINED: @@ -476,694 +485,1447 @@ struct EnumTraits<VkImageLayout> { template <typename Visitor> inline bool Iterate(Visitor* visitor, VkExtent3D* extents) { + return visitor->Visit("width", &extents->width) && + visitor->Visit("height", &extents->height) && + visitor->Visit("depth", &extents->depth); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkConformanceVersionKHR* version) { + return visitor->Visit("major", &version->major) && + visitor->Visit("minor", &version->minor) && + visitor->Visit("subminor", &version->subminor) && + visitor->Visit("patch", &version->patch); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkMemoryType* type) { + return visitor->Visit("propertyFlags", &type->propertyFlags) && + visitor->Visit("heapIndex", &type->heapIndex); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkMemoryHeap* heap) { + return visitor->Visit("size", &heap->size) && + visitor->Visit("flags", &heap->flags); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonCore11* core) { + return visitor->Visit("properties", &core->properties) && + visitor->Visit("features", &core->features); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonCore12* core) { + return visitor->Visit("properties", &core->properties) && + visitor->Visit("features", &core->features); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonCore13* core) { + return visitor->Visit("properties", &core->properties) && + visitor->Visit("features", &core->features); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonCore14* core) { + return visitor->Visit("properties", &core->properties) && + visitor->Visit("features", &core->features); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonKHRVariablePointers* structs) { + return visitor->Visit("variablePointerFeaturesKHR", + &structs->variable_pointer_features_khr) && + visitor->Visit("variablePointersFeaturesKHR", + &structs->variable_pointers_features_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonKHRShaderFloat16Int8* structs) { + return visitor->Visit("shaderFloat16Int8FeaturesKHR", + &structs->shader_float16_int8_features_khr) && + visitor->Visit("float16Int8FeaturesKHR", + &structs->float16_int8_features_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonExtImage2dViewOf3d* structs) { + return visitor->Visit("image2DViewOf3DFeaturesEXT", + &structs->image_2d_view_of_3d_features_ext); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonExtCustomBorderColor* structs) { + return visitor->Visit("customBorderColorFeaturesEXT", + &structs->custom_border_color_features_ext); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkJsonExtPrimitiveTopologyListRestart* structs) { + return visitor->Visit("primitiveTopologyListRestartFeaturesEXT", + &structs->primitive_topology_list_restart_features_ext); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonExtProvokingVertex* structs) { + return visitor->Visit("provokingVertexFeaturesEXT", + &structs->provoking_vertex_features_ext); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonKHRIndexTypeUint8* structs) { + return visitor->Visit("indexTypeUint8FeaturesKHR", + &structs->index_type_uint8_features_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonExtIndexTypeUint8* structs) { + return visitor->Visit("indexTypeUint8FeaturesEXT", + &structs->index_type_uint8_features_ext); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkJsonKHRVertexAttributeDivisor* structs) { + return visitor->Visit("vertexAttributeDivisorFeaturesKHR", + &structs->vertex_attribute_divisor_features_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkJsonExtVertexAttributeDivisor* structs) { + return visitor->Visit("vertexAttributeDivisorFeaturesEXT", + &structs->vertex_attribute_divisor_features_ext); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonExtTransformFeedback* structs) { + return visitor->Visit("transformFeedbackFeaturesEXT", + &structs->transform_feedback_features_ext); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkJsonKHRShaderSubgroupUniformControlFlow* structs) { + return visitor->Visit( + "shaderSubgroupUniformControlFlowFeaturesKHR", + &structs->shader_subgroup_uniform_control_flow_features_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkJsonKHRShaderSubgroupExtendedTypes* structs) { + return visitor->Visit("shaderSubgroupExtendedTypesFeaturesKHR", + &structs->shader_subgroup_extended_types_features_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonKHR8bitStorage* structs) { + return visitor->Visit("bit8StorageFeaturesKHR", + &structs->bit8_storage_features_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkJsonKHRShaderIntegerDotProduct* structs) { + return visitor->Visit("shaderIntegerDotProductFeaturesKHR", + &structs->shader_integer_dot_product_features_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkJsonIMGRelaxedLineRasterization* structs) { + return visitor->Visit("relaxedLineRasterizationFeaturesIMG", + &structs->relaxed_line_rasterization_features_img); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonKHRLineRasterization* structs) { + return visitor->Visit("lineRasterizationFeaturesKHR", + &structs->line_rasterization_features_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonExtLineRasterization* structs) { + return visitor->Visit("lineRasterizationFeaturesEXT", + &structs->line_rasterization_features_ext); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkJsonExtPrimitivesGeneratedQuery* structs) { + return visitor->Visit("primitivesGeneratedQueryFeaturesEXT", + &structs->primitives_generated_query_features_ext); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonKHRShaderFloatControls* structs) { + return visitor->Visit("floatControlsPropertiesKHR", + &structs->float_controls_properties_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkJsonKHRDriverProperties* structs) { + return visitor->Visit("driverPropertiesKHR", &structs->driver_properties_khr); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceFloatControlsProperties* properties) { return - visitor->Visit("width", &extents->width) && - visitor->Visit("height", &extents->height) && - visitor->Visit("depth", &extents->depth); + + visitor->Visit("denormBehaviorIndependence", + &properties->denormBehaviorIndependence) && + visitor->Visit("roundingModeIndependence", + &properties->roundingModeIndependence) && + visitor->Visit("shaderSignedZeroInfNanPreserveFloat16", + &properties->shaderSignedZeroInfNanPreserveFloat16) && + visitor->Visit("shaderSignedZeroInfNanPreserveFloat32", + &properties->shaderSignedZeroInfNanPreserveFloat32) && + visitor->Visit("shaderSignedZeroInfNanPreserveFloat64", + &properties->shaderSignedZeroInfNanPreserveFloat64) && + visitor->Visit("shaderDenormPreserveFloat16", + &properties->shaderDenormPreserveFloat16) && + visitor->Visit("shaderDenormPreserveFloat32", + &properties->shaderDenormPreserveFloat32) && + visitor->Visit("shaderDenormPreserveFloat64", + &properties->shaderDenormPreserveFloat64) && + visitor->Visit("shaderDenormFlushToZeroFloat16", + &properties->shaderDenormFlushToZeroFloat16) && + visitor->Visit("shaderDenormFlushToZeroFloat32", + &properties->shaderDenormFlushToZeroFloat32) && + visitor->Visit("shaderDenormFlushToZeroFloat64", + &properties->shaderDenormFlushToZeroFloat64) && + visitor->Visit("shaderRoundingModeRTEFloat16", + &properties->shaderRoundingModeRTEFloat16) && + visitor->Visit("shaderRoundingModeRTEFloat32", + &properties->shaderRoundingModeRTEFloat32) && + visitor->Visit("shaderRoundingModeRTEFloat64", + &properties->shaderRoundingModeRTEFloat64) && + visitor->Visit("shaderRoundingModeRTZFloat16", + &properties->shaderRoundingModeRTZFloat16) && + visitor->Visit("shaderRoundingModeRTZFloat32", + &properties->shaderRoundingModeRTZFloat32) && + visitor->Visit("shaderRoundingModeRTZFloat64", + &properties->shaderRoundingModeRTZFloat64); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkImageFormatProperties* properties) { +inline bool Iterate(Visitor* visitor, VkPhysicalDeviceProperties* properties) { return - visitor->Visit("maxExtent", &properties->maxExtent) && - visitor->Visit("maxMipLevels", &properties->maxMipLevels) && - visitor->Visit("maxArrayLayers", &properties->maxArrayLayers) && - visitor->Visit("sampleCounts", &properties->sampleCounts) && - visitor->Visit("maxResourceSize", &properties->maxResourceSize); + + visitor->Visit("apiVersion", &properties->apiVersion) && + visitor->Visit("driverVersion", &properties->driverVersion) && + visitor->Visit("vendorID", &properties->vendorID) && + visitor->Visit("deviceID", &properties->deviceID) && + visitor->Visit("deviceType", &properties->deviceType) && + visitor->Visit("deviceName", &properties->deviceName) && + visitor->Visit("pipelineCacheUUID", &properties->pipelineCacheUUID) && + visitor->Visit("limits", &properties->limits) && + visitor->Visit("sparseProperties", &properties->sparseProperties); } -// clang-format off template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkPhysicalDeviceLimits* limits) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceMemoryProperties* properties) { return - visitor->Visit("maxImageDimension1D", &limits->maxImageDimension1D) && - visitor->Visit("maxImageDimension2D", &limits->maxImageDimension2D) && - visitor->Visit("maxImageDimension3D", &limits->maxImageDimension3D) && - visitor->Visit("maxImageDimensionCube", &limits->maxImageDimensionCube) && - visitor->Visit("maxImageArrayLayers", &limits->maxImageArrayLayers) && - visitor->Visit("maxTexelBufferElements", &limits->maxTexelBufferElements) && - visitor->Visit("maxUniformBufferRange", &limits->maxUniformBufferRange) && - visitor->Visit("maxStorageBufferRange", &limits->maxStorageBufferRange) && - visitor->Visit("maxPushConstantsSize", &limits->maxPushConstantsSize) && - visitor->Visit("maxMemoryAllocationCount", &limits->maxMemoryAllocationCount) && - visitor->Visit("maxSamplerAllocationCount", &limits->maxSamplerAllocationCount) && - visitor->Visit("bufferImageGranularity", &limits->bufferImageGranularity) && - visitor->Visit("sparseAddressSpaceSize", &limits->sparseAddressSpaceSize) && - visitor->Visit("maxBoundDescriptorSets", &limits->maxBoundDescriptorSets) && - visitor->Visit("maxPerStageDescriptorSamplers", &limits->maxPerStageDescriptorSamplers) && - visitor->Visit("maxPerStageDescriptorUniformBuffers", &limits->maxPerStageDescriptorUniformBuffers) && - visitor->Visit("maxPerStageDescriptorStorageBuffers", &limits->maxPerStageDescriptorStorageBuffers) && - visitor->Visit("maxPerStageDescriptorSampledImages", &limits->maxPerStageDescriptorSampledImages) && - visitor->Visit("maxPerStageDescriptorStorageImages", &limits->maxPerStageDescriptorStorageImages) && - visitor->Visit("maxPerStageDescriptorInputAttachments", &limits->maxPerStageDescriptorInputAttachments) && - visitor->Visit("maxPerStageResources", &limits->maxPerStageResources) && - visitor->Visit("maxDescriptorSetSamplers", &limits->maxDescriptorSetSamplers) && - visitor->Visit("maxDescriptorSetUniformBuffers", &limits->maxDescriptorSetUniformBuffers) && - visitor->Visit("maxDescriptorSetUniformBuffersDynamic", &limits->maxDescriptorSetUniformBuffersDynamic) && - visitor->Visit("maxDescriptorSetStorageBuffers", &limits->maxDescriptorSetStorageBuffers) && - visitor->Visit("maxDescriptorSetStorageBuffersDynamic", &limits->maxDescriptorSetStorageBuffersDynamic) && - visitor->Visit("maxDescriptorSetSampledImages", &limits->maxDescriptorSetSampledImages) && - visitor->Visit("maxDescriptorSetStorageImages", &limits->maxDescriptorSetStorageImages) && - visitor->Visit("maxDescriptorSetInputAttachments", &limits->maxDescriptorSetInputAttachments) && - visitor->Visit("maxVertexInputAttributes", &limits->maxVertexInputAttributes) && - visitor->Visit("maxVertexInputBindings", &limits->maxVertexInputBindings) && - visitor->Visit("maxVertexInputAttributeOffset", &limits->maxVertexInputAttributeOffset) && - visitor->Visit("maxVertexInputBindingStride", &limits->maxVertexInputBindingStride) && - visitor->Visit("maxVertexOutputComponents", &limits->maxVertexOutputComponents) && - visitor->Visit("maxTessellationGenerationLevel", &limits->maxTessellationGenerationLevel) && - visitor->Visit("maxTessellationPatchSize", &limits->maxTessellationPatchSize) && - visitor->Visit("maxTessellationControlPerVertexInputComponents", &limits->maxTessellationControlPerVertexInputComponents) && - visitor->Visit("maxTessellationControlPerVertexOutputComponents", &limits->maxTessellationControlPerVertexOutputComponents) && - visitor->Visit("maxTessellationControlPerPatchOutputComponents", &limits->maxTessellationControlPerPatchOutputComponents) && - visitor->Visit("maxTessellationControlTotalOutputComponents", &limits->maxTessellationControlTotalOutputComponents) && - visitor->Visit("maxTessellationEvaluationInputComponents", &limits->maxTessellationEvaluationInputComponents) && - visitor->Visit("maxTessellationEvaluationOutputComponents", &limits->maxTessellationEvaluationOutputComponents) && - visitor->Visit("maxGeometryShaderInvocations", &limits->maxGeometryShaderInvocations) && - visitor->Visit("maxGeometryInputComponents", &limits->maxGeometryInputComponents) && - visitor->Visit("maxGeometryOutputComponents", &limits->maxGeometryOutputComponents) && - visitor->Visit("maxGeometryOutputVertices", &limits->maxGeometryOutputVertices) && - visitor->Visit("maxGeometryTotalOutputComponents", &limits->maxGeometryTotalOutputComponents) && - visitor->Visit("maxFragmentInputComponents", &limits->maxFragmentInputComponents) && - visitor->Visit("maxFragmentOutputAttachments", &limits->maxFragmentOutputAttachments) && - visitor->Visit("maxFragmentDualSrcAttachments", &limits->maxFragmentDualSrcAttachments) && - visitor->Visit("maxFragmentCombinedOutputResources", &limits->maxFragmentCombinedOutputResources) && - visitor->Visit("maxComputeSharedMemorySize", &limits->maxComputeSharedMemorySize) && - visitor->Visit("maxComputeWorkGroupCount", &limits->maxComputeWorkGroupCount) && - visitor->Visit("maxComputeWorkGroupInvocations", &limits->maxComputeWorkGroupInvocations) && - visitor->Visit("maxComputeWorkGroupSize", &limits->maxComputeWorkGroupSize) && - visitor->Visit("subPixelPrecisionBits", &limits->subPixelPrecisionBits) && - visitor->Visit("subTexelPrecisionBits", &limits->subTexelPrecisionBits) && - visitor->Visit("mipmapPrecisionBits", &limits->mipmapPrecisionBits) && - visitor->Visit("maxDrawIndexedIndexValue", &limits->maxDrawIndexedIndexValue) && - visitor->Visit("maxDrawIndirectCount", &limits->maxDrawIndirectCount) && - visitor->Visit("maxSamplerLodBias", &limits->maxSamplerLodBias) && - visitor->Visit("maxSamplerAnisotropy", &limits->maxSamplerAnisotropy) && - visitor->Visit("maxViewports", &limits->maxViewports) && - visitor->Visit("maxViewportDimensions", &limits->maxViewportDimensions) && - visitor->Visit("viewportBoundsRange", &limits->viewportBoundsRange) && - visitor->Visit("viewportSubPixelBits", &limits->viewportSubPixelBits) && - visitor->Visit("minMemoryMapAlignment", &limits->minMemoryMapAlignment) && - visitor->Visit("minTexelBufferOffsetAlignment", &limits->minTexelBufferOffsetAlignment) && - visitor->Visit("minUniformBufferOffsetAlignment", &limits->minUniformBufferOffsetAlignment) && - visitor->Visit("minStorageBufferOffsetAlignment", &limits->minStorageBufferOffsetAlignment) && - visitor->Visit("minTexelOffset", &limits->minTexelOffset) && - visitor->Visit("maxTexelOffset", &limits->maxTexelOffset) && - visitor->Visit("minTexelGatherOffset", &limits->minTexelGatherOffset) && - visitor->Visit("maxTexelGatherOffset", &limits->maxTexelGatherOffset) && - visitor->Visit("minInterpolationOffset", &limits->minInterpolationOffset) && - visitor->Visit("maxInterpolationOffset", &limits->maxInterpolationOffset) && - visitor->Visit("subPixelInterpolationOffsetBits", &limits->subPixelInterpolationOffsetBits) && - visitor->Visit("maxFramebufferWidth", &limits->maxFramebufferWidth) && - visitor->Visit("maxFramebufferHeight", &limits->maxFramebufferHeight) && - visitor->Visit("maxFramebufferLayers", &limits->maxFramebufferLayers) && - visitor->Visit("framebufferColorSampleCounts", &limits->framebufferColorSampleCounts) && - visitor->Visit("framebufferDepthSampleCounts", &limits->framebufferDepthSampleCounts) && - visitor->Visit("framebufferStencilSampleCounts", &limits->framebufferStencilSampleCounts) && - visitor->Visit("framebufferNoAttachmentsSampleCounts", &limits->framebufferNoAttachmentsSampleCounts) && - visitor->Visit("maxColorAttachments", &limits->maxColorAttachments) && - visitor->Visit("sampledImageColorSampleCounts", &limits->sampledImageColorSampleCounts) && - visitor->Visit("sampledImageIntegerSampleCounts", &limits->sampledImageIntegerSampleCounts) && - visitor->Visit("sampledImageDepthSampleCounts", &limits->sampledImageDepthSampleCounts) && - visitor->Visit("sampledImageStencilSampleCounts", &limits->sampledImageStencilSampleCounts) && - visitor->Visit("storageImageSampleCounts", &limits->storageImageSampleCounts) && - visitor->Visit("maxSampleMaskWords", &limits->maxSampleMaskWords) && - visitor->Visit("timestampComputeAndGraphics", &limits->timestampComputeAndGraphics) && - visitor->Visit("timestampPeriod", &limits->timestampPeriod) && - visitor->Visit("maxClipDistances", &limits->maxClipDistances) && - visitor->Visit("maxCullDistances", &limits->maxCullDistances) && - visitor->Visit("maxCombinedClipAndCullDistances", &limits->maxCombinedClipAndCullDistances) && - visitor->Visit("discreteQueuePriorities", &limits->discreteQueuePriorities) && - visitor->Visit("pointSizeRange", &limits->pointSizeRange) && - visitor->Visit("lineWidthRange", &limits->lineWidthRange) && - visitor->Visit("pointSizeGranularity", &limits->pointSizeGranularity) && - visitor->Visit("lineWidthGranularity", &limits->lineWidthGranularity) && - visitor->Visit("strictLines", &limits->strictLines) && - visitor->Visit("standardSampleLocations", &limits->standardSampleLocations) && - visitor->Visit("optimalBufferCopyOffsetAlignment", &limits->optimalBufferCopyOffsetAlignment) && - visitor->Visit("optimalBufferCopyRowPitchAlignment", &limits->optimalBufferCopyRowPitchAlignment) && - visitor->Visit("nonCoherentAtomSize", &limits->nonCoherentAtomSize); + + visitor->Visit("memoryTypeCount", &properties->memoryTypeCount) && + visitor->VisitArray("memoryTypes", properties->memoryTypeCount, + &properties->memoryTypes) && + visitor->Visit("memoryHeapCount", &properties->memoryHeapCount) && + visitor->VisitArray("memoryHeaps", properties->memoryHeapCount, + &properties->memoryHeaps); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceSparseProperties* properties) { + VkPhysicalDeviceSubgroupProperties* properties) { return - visitor->Visit("residencyStandard2DBlockShape", &properties->residencyStandard2DBlockShape) && - visitor->Visit("residencyStandard2DMultisampleBlockShape", &properties->residencyStandard2DMultisampleBlockShape) && - visitor->Visit("residencyStandard3DBlockShape", &properties->residencyStandard3DBlockShape) && - visitor->Visit("residencyAlignedMipSize", &properties->residencyAlignedMipSize) && - visitor->Visit("residencyNonResidentStrict", &properties->residencyNonResidentStrict); + + visitor->Visit("subgroupSize", &properties->subgroupSize) && + visitor->Visit("supportedStages", &properties->supportedStages) && + visitor->Visit("supportedOperations", &properties->supportedOperations) && + visitor->Visit("quadOperationsInAllStages", + &properties->quadOperationsInAllStages); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceProperties* properties) { + VkPhysicalDevicePointClippingProperties* properties) { return - visitor->Visit("apiVersion", &properties->apiVersion) && - visitor->Visit("driverVersion", &properties->driverVersion) && - visitor->Visit("vendorID", &properties->vendorID) && - visitor->Visit("deviceID", &properties->deviceID) && - visitor->Visit("deviceType", &properties->deviceType) && - visitor->Visit("deviceName", &properties->deviceName) && - visitor->Visit("pipelineCacheUUID", &properties->pipelineCacheUUID) && - visitor->Visit("limits", &properties->limits) && - visitor->Visit("sparseProperties", &properties->sparseProperties); + + visitor->Visit("pointClippingBehavior", + &properties->pointClippingBehavior); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkPhysicalDeviceFeatures* features) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceMultiviewProperties* properties) { return - visitor->Visit("robustBufferAccess", &features->robustBufferAccess) && - visitor->Visit("fullDrawIndexUint32", &features->fullDrawIndexUint32) && - visitor->Visit("imageCubeArray", &features->imageCubeArray) && - visitor->Visit("independentBlend", &features->independentBlend) && - visitor->Visit("geometryShader", &features->geometryShader) && - visitor->Visit("tessellationShader", &features->tessellationShader) && - visitor->Visit("sampleRateShading", &features->sampleRateShading) && - visitor->Visit("dualSrcBlend", &features->dualSrcBlend) && - visitor->Visit("logicOp", &features->logicOp) && - visitor->Visit("multiDrawIndirect", &features->multiDrawIndirect) && - visitor->Visit("drawIndirectFirstInstance", &features->drawIndirectFirstInstance) && - visitor->Visit("depthClamp", &features->depthClamp) && - visitor->Visit("depthBiasClamp", &features->depthBiasClamp) && - visitor->Visit("fillModeNonSolid", &features->fillModeNonSolid) && - visitor->Visit("depthBounds", &features->depthBounds) && - visitor->Visit("wideLines", &features->wideLines) && - visitor->Visit("largePoints", &features->largePoints) && - visitor->Visit("alphaToOne", &features->alphaToOne) && - visitor->Visit("multiViewport", &features->multiViewport) && - visitor->Visit("samplerAnisotropy", &features->samplerAnisotropy) && - visitor->Visit("textureCompressionETC2", &features->textureCompressionETC2) && - visitor->Visit("textureCompressionASTC_LDR", &features->textureCompressionASTC_LDR) && - visitor->Visit("textureCompressionBC", &features->textureCompressionBC) && - visitor->Visit("occlusionQueryPrecise", &features->occlusionQueryPrecise) && - visitor->Visit("pipelineStatisticsQuery", &features->pipelineStatisticsQuery) && - visitor->Visit("vertexPipelineStoresAndAtomics", &features->vertexPipelineStoresAndAtomics) && - visitor->Visit("fragmentStoresAndAtomics", &features->fragmentStoresAndAtomics) && - visitor->Visit("shaderTessellationAndGeometryPointSize", &features->shaderTessellationAndGeometryPointSize) && - visitor->Visit("shaderImageGatherExtended", &features->shaderImageGatherExtended) && - visitor->Visit("shaderStorageImageExtendedFormats", &features->shaderStorageImageExtendedFormats) && - visitor->Visit("shaderStorageImageMultisample", &features->shaderStorageImageMultisample) && - visitor->Visit("shaderStorageImageReadWithoutFormat", &features->shaderStorageImageReadWithoutFormat) && - visitor->Visit("shaderStorageImageWriteWithoutFormat", &features->shaderStorageImageWriteWithoutFormat) && - visitor->Visit("shaderUniformBufferArrayDynamicIndexing", &features->shaderUniformBufferArrayDynamicIndexing) && - visitor->Visit("shaderSampledImageArrayDynamicIndexing", &features->shaderSampledImageArrayDynamicIndexing) && - visitor->Visit("shaderStorageBufferArrayDynamicIndexing", &features->shaderStorageBufferArrayDynamicIndexing) && - visitor->Visit("shaderStorageImageArrayDynamicIndexing", &features->shaderStorageImageArrayDynamicIndexing) && - visitor->Visit("shaderClipDistance", &features->shaderClipDistance) && - visitor->Visit("shaderCullDistance", &features->shaderCullDistance) && - visitor->Visit("shaderFloat64", &features->shaderFloat64) && - visitor->Visit("shaderInt64", &features->shaderInt64) && - visitor->Visit("shaderInt16", &features->shaderInt16) && - visitor->Visit("shaderResourceResidency", &features->shaderResourceResidency) && - visitor->Visit("shaderResourceMinLod", &features->shaderResourceMinLod) && - visitor->Visit("sparseBinding", &features->sparseBinding) && - visitor->Visit("sparseResidencyBuffer", &features->sparseResidencyBuffer) && - visitor->Visit("sparseResidencyImage2D", &features->sparseResidencyImage2D) && - visitor->Visit("sparseResidencyImage3D", &features->sparseResidencyImage3D) && - visitor->Visit("sparseResidency2Samples", &features->sparseResidency2Samples) && - visitor->Visit("sparseResidency4Samples", &features->sparseResidency4Samples) && - visitor->Visit("sparseResidency8Samples", &features->sparseResidency8Samples) && - visitor->Visit("sparseResidency16Samples", &features->sparseResidency16Samples) && - visitor->Visit("sparseResidencyAliased", &features->sparseResidencyAliased) && - visitor->Visit("variableMultisampleRate", &features->variableMultisampleRate) && - visitor->Visit("inheritedQueries", &features->inheritedQueries); + + visitor->Visit("maxMultiviewViewCount", + &properties->maxMultiviewViewCount) && + visitor->Visit("maxMultiviewInstanceIndex", + &properties->maxMultiviewInstanceIndex); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkJsonCore12* core) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceIDProperties* properties) { return - visitor->Visit("features", &core->features) && - visitor->Visit("properties", &core->properties); + + visitor->Visit("deviceUUID", &properties->deviceUUID) && + visitor->Visit("driverUUID", &properties->driverUUID) && + visitor->Visit("deviceLUID", &properties->deviceLUID) && + visitor->Visit("deviceNodeMask", &properties->deviceNodeMask) && + visitor->Visit("deviceLUIDValid", &properties->deviceLUIDValid); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan12Properties* properties) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceMaintenance3Properties* properties) { return - visitor->Visit("driverID", &properties->driverID) && - visitor->Visit("driverName", &properties->driverName) && - visitor->Visit("driverInfo", &properties->driverInfo) && - visitor->Visit("conformanceVersion", &properties->conformanceVersion) && - visitor->Visit("denormBehaviorIndependence", &properties->denormBehaviorIndependence) && - visitor->Visit("roundingModeIndependence", &properties->roundingModeIndependence) && - visitor->Visit("shaderSignedZeroInfNanPreserveFloat16", &properties->shaderSignedZeroInfNanPreserveFloat16) && - visitor->Visit("shaderSignedZeroInfNanPreserveFloat32", &properties->shaderSignedZeroInfNanPreserveFloat32) && - visitor->Visit("shaderSignedZeroInfNanPreserveFloat64", &properties->shaderSignedZeroInfNanPreserveFloat64) && - visitor->Visit("shaderDenormPreserveFloat16", &properties->shaderDenormPreserveFloat16) && - visitor->Visit("shaderDenormPreserveFloat32", &properties->shaderDenormPreserveFloat32) && - visitor->Visit("shaderDenormPreserveFloat64", &properties->shaderDenormPreserveFloat64) && - visitor->Visit("shaderDenormFlushToZeroFloat16", &properties->shaderDenormFlushToZeroFloat16) && - visitor->Visit("shaderDenormFlushToZeroFloat32", &properties->shaderDenormFlushToZeroFloat32) && - visitor->Visit("shaderDenormFlushToZeroFloat64", &properties->shaderDenormFlushToZeroFloat64) && - visitor->Visit("shaderRoundingModeRTEFloat16", &properties->shaderRoundingModeRTEFloat16) && - visitor->Visit("shaderRoundingModeRTEFloat32", &properties->shaderRoundingModeRTEFloat32) && - visitor->Visit("shaderRoundingModeRTEFloat64", &properties->shaderRoundingModeRTEFloat64) && - visitor->Visit("shaderRoundingModeRTZFloat16", &properties->shaderRoundingModeRTZFloat16) && - visitor->Visit("shaderRoundingModeRTZFloat32", &properties->shaderRoundingModeRTZFloat32) && - visitor->Visit("shaderRoundingModeRTZFloat64", &properties->shaderRoundingModeRTZFloat64) && - visitor->Visit("maxUpdateAfterBindDescriptorsInAllPools", &properties->maxUpdateAfterBindDescriptorsInAllPools) && - visitor->Visit("shaderUniformBufferArrayNonUniformIndexingNative", &properties->shaderUniformBufferArrayNonUniformIndexingNative) && - visitor->Visit("shaderSampledImageArrayNonUniformIndexingNative", &properties->shaderSampledImageArrayNonUniformIndexingNative) && - visitor->Visit("shaderStorageBufferArrayNonUniformIndexingNative", &properties->shaderStorageBufferArrayNonUniformIndexingNative) && - visitor->Visit("shaderStorageImageArrayNonUniformIndexingNative", &properties->shaderStorageImageArrayNonUniformIndexingNative) && - visitor->Visit("shaderInputAttachmentArrayNonUniformIndexingNative", &properties->shaderInputAttachmentArrayNonUniformIndexingNative) && - visitor->Visit("robustBufferAccessUpdateAfterBind", &properties->robustBufferAccessUpdateAfterBind) && - visitor->Visit("quadDivergentImplicitLod", &properties->quadDivergentImplicitLod) && - visitor->Visit("maxPerStageDescriptorUpdateAfterBindSamplers", &properties->maxPerStageDescriptorUpdateAfterBindSamplers) && - visitor->Visit("maxPerStageDescriptorUpdateAfterBindUniformBuffers", &properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers) && - visitor->Visit("maxPerStageDescriptorUpdateAfterBindStorageBuffers", &properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers) && - visitor->Visit("maxPerStageDescriptorUpdateAfterBindSampledImages", &properties->maxPerStageDescriptorUpdateAfterBindSampledImages) && - visitor->Visit("maxPerStageDescriptorUpdateAfterBindStorageImages", &properties->maxPerStageDescriptorUpdateAfterBindStorageImages) && - visitor->Visit("maxPerStageDescriptorUpdateAfterBindInputAttachments", &properties->maxPerStageDescriptorUpdateAfterBindInputAttachments) && - visitor->Visit("maxPerStageUpdateAfterBindResources", &properties->maxPerStageUpdateAfterBindResources) && - visitor->Visit("maxDescriptorSetUpdateAfterBindSamplers", &properties->maxDescriptorSetUpdateAfterBindSamplers) && - visitor->Visit("maxDescriptorSetUpdateAfterBindUniformBuffers", &properties->maxDescriptorSetUpdateAfterBindUniformBuffers) && - visitor->Visit("maxDescriptorSetUpdateAfterBindUniformBuffersDynamic", &properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic) && - visitor->Visit("maxDescriptorSetUpdateAfterBindStorageBuffers", &properties->maxDescriptorSetUpdateAfterBindStorageBuffers) && - visitor->Visit("maxDescriptorSetUpdateAfterBindStorageBuffersDynamic", &properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic) && - visitor->Visit("maxDescriptorSetUpdateAfterBindSampledImages", &properties->maxDescriptorSetUpdateAfterBindSampledImages) && - visitor->Visit("maxDescriptorSetUpdateAfterBindStorageImages", &properties->maxDescriptorSetUpdateAfterBindStorageImages) && - visitor->Visit("maxDescriptorSetUpdateAfterBindInputAttachments", &properties->maxDescriptorSetUpdateAfterBindInputAttachments) && - visitor->Visit("supportedDepthResolveModes", &properties->supportedDepthResolveModes) && - visitor->Visit("supportedStencilResolveModes", &properties->supportedStencilResolveModes) && - visitor->Visit("independentResolveNone", &properties->independentResolveNone) && - visitor->Visit("independentResolve", &properties->independentResolve) && - visitor->Visit("filterMinmaxSingleComponentFormats", &properties->filterMinmaxSingleComponentFormats) && - visitor->Visit("filterMinmaxImageComponentMapping", &properties->filterMinmaxImageComponentMapping) && - visitor->Visit("maxTimelineSemaphoreValueDifference", &properties->maxTimelineSemaphoreValueDifference) && - visitor->Visit("framebufferIntegerColorSampleCounts", &properties->framebufferIntegerColorSampleCounts); -} - -template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan12Features* features) { + + visitor->Visit("maxPerSetDescriptors", + &properties->maxPerSetDescriptors) && + visitor->Visit("maxMemoryAllocationSize", + &properties->maxMemoryAllocationSize); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceSparseProperties* properties) { return - visitor->Visit("samplerMirrorClampToEdge", &features->samplerMirrorClampToEdge) && - visitor->Visit("drawIndirectCount", &features->drawIndirectCount) && - visitor->Visit("storageBuffer8BitAccess", &features->storageBuffer8BitAccess) && - visitor->Visit("uniformAndStorageBuffer8BitAccess", &features->uniformAndStorageBuffer8BitAccess) && - visitor->Visit("storagePushConstant8", &features->storagePushConstant8) && - visitor->Visit("shaderBufferInt64Atomics", &features->shaderBufferInt64Atomics) && - visitor->Visit("shaderSharedInt64Atomics", &features->shaderSharedInt64Atomics) && - visitor->Visit("shaderFloat16", &features->shaderFloat16) && - visitor->Visit("shaderInt8", &features->shaderInt8) && - visitor->Visit("descriptorIndexing", &features->descriptorIndexing) && - visitor->Visit("shaderInputAttachmentArrayDynamicIndexing", &features->shaderInputAttachmentArrayDynamicIndexing) && - visitor->Visit("shaderUniformTexelBufferArrayDynamicIndexing", &features->shaderUniformTexelBufferArrayDynamicIndexing) && - visitor->Visit("shaderStorageTexelBufferArrayDynamicIndexing", &features->shaderStorageTexelBufferArrayDynamicIndexing) && - visitor->Visit("shaderUniformBufferArrayNonUniformIndexing", &features->shaderUniformBufferArrayNonUniformIndexing) && - visitor->Visit("shaderSampledImageArrayNonUniformIndexing", &features->shaderSampledImageArrayNonUniformIndexing) && - visitor->Visit("shaderStorageBufferArrayNonUniformIndexing", &features->shaderStorageBufferArrayNonUniformIndexing) && - visitor->Visit("shaderStorageImageArrayNonUniformIndexing", &features->shaderStorageImageArrayNonUniformIndexing) && - visitor->Visit("shaderInputAttachmentArrayNonUniformIndexing", &features->shaderInputAttachmentArrayNonUniformIndexing) && - visitor->Visit("shaderUniformTexelBufferArrayNonUniformIndexing", &features->shaderUniformTexelBufferArrayNonUniformIndexing) && - visitor->Visit("shaderStorageTexelBufferArrayNonUniformIndexing", &features->shaderStorageTexelBufferArrayNonUniformIndexing) && - visitor->Visit("descriptorBindingUniformBufferUpdateAfterBind", &features->descriptorBindingUniformBufferUpdateAfterBind) && - visitor->Visit("descriptorBindingSampledImageUpdateAfterBind", &features->descriptorBindingSampledImageUpdateAfterBind) && - visitor->Visit("descriptorBindingStorageImageUpdateAfterBind", &features->descriptorBindingStorageImageUpdateAfterBind) && - visitor->Visit("descriptorBindingStorageBufferUpdateAfterBind", &features->descriptorBindingStorageBufferUpdateAfterBind) && - visitor->Visit("descriptorBindingUniformTexelBufferUpdateAfterBind", &features->descriptorBindingUniformTexelBufferUpdateAfterBind) && - visitor->Visit("descriptorBindingStorageTexelBufferUpdateAfterBind", &features->descriptorBindingStorageTexelBufferUpdateAfterBind) && - visitor->Visit("descriptorBindingUpdateUnusedWhilePending", &features->descriptorBindingUpdateUnusedWhilePending) && - visitor->Visit("descriptorBindingPartiallyBound", &features->descriptorBindingPartiallyBound) && - visitor->Visit("descriptorBindingVariableDescriptorCount", &features->descriptorBindingVariableDescriptorCount) && - visitor->Visit("runtimeDescriptorArray", &features->runtimeDescriptorArray) && - visitor->Visit("samplerFilterMinmax", &features->samplerFilterMinmax) && - visitor->Visit("scalarBlockLayout", &features->scalarBlockLayout) && - visitor->Visit("imagelessFramebuffer", &features->imagelessFramebuffer) && - visitor->Visit("uniformBufferStandardLayout", &features->uniformBufferStandardLayout) && - visitor->Visit("shaderSubgroupExtendedTypes", &features->shaderSubgroupExtendedTypes) && - visitor->Visit("separateDepthStencilLayouts", &features->separateDepthStencilLayouts) && - visitor->Visit("hostQueryReset", &features->hostQueryReset) && - visitor->Visit("timelineSemaphore", &features->timelineSemaphore) && - visitor->Visit("bufferDeviceAddress", &features->bufferDeviceAddress) && - visitor->Visit("bufferDeviceAddressCaptureReplay", &features->bufferDeviceAddressCaptureReplay) && - visitor->Visit("bufferDeviceAddressMultiDevice", &features->bufferDeviceAddressMultiDevice) && - visitor->Visit("vulkanMemoryModel", &features->vulkanMemoryModel) && - visitor->Visit("vulkanMemoryModelDeviceScope", &features->vulkanMemoryModelDeviceScope) && - visitor->Visit("vulkanMemoryModelAvailabilityVisibilityChains", &features->vulkanMemoryModelAvailabilityVisibilityChains) && - visitor->Visit("shaderOutputViewportIndex", &features->shaderOutputViewportIndex) && - visitor->Visit("shaderOutputLayer", &features->shaderOutputLayer) && - visitor->Visit("subgroupBroadcastDynamicId", &features->subgroupBroadcastDynamicId); + + visitor->Visit("residencyStandard2DBlockShape", + &properties->residencyStandard2DBlockShape) && + visitor->Visit("residencyStandard2DMultisampleBlockShape", + &properties->residencyStandard2DMultisampleBlockShape) && + visitor->Visit("residencyStandard3DBlockShape", + &properties->residencyStandard3DBlockShape) && + visitor->Visit("residencyAlignedMipSize", + &properties->residencyAlignedMipSize) && + visitor->Visit("residencyNonResidentStrict", + &properties->residencyNonResidentStrict); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkJsonCore13* core) { +inline bool Iterate(Visitor* visitor, VkImageFormatProperties* properties) { return - visitor->Visit("features", &core->features) && - visitor->Visit("properties", &core->properties); + + visitor->Visit("maxExtent", &properties->maxExtent) && + visitor->Visit("maxMipLevels", &properties->maxMipLevels) && + visitor->Visit("maxArrayLayers", &properties->maxArrayLayers) && + visitor->Visit("sampleCounts", &properties->sampleCounts) && + visitor->Visit("maxResourceSize", &properties->maxResourceSize); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan13Properties* properties) { +inline bool Iterate(Visitor* visitor, VkQueueFamilyProperties* properties) { return - visitor->Visit("minSubgroupSize", &properties->minSubgroupSize) && - visitor->Visit("maxSubgroupSize", &properties->maxSubgroupSize) && - visitor->Visit("maxComputeWorkgroupSubgroups", &properties->maxComputeWorkgroupSubgroups) && - visitor->Visit("requiredSubgroupSizeStages", &properties->requiredSubgroupSizeStages) && - visitor->Visit("maxInlineUniformBlockSize", &properties->maxInlineUniformBlockSize) && - visitor->Visit("maxPerStageDescriptorInlineUniformBlocks", &properties->maxPerStageDescriptorInlineUniformBlocks) && - visitor->Visit("maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks", &properties->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks) && - visitor->Visit("maxDescriptorSetInlineUniformBlocks", &properties->maxDescriptorSetInlineUniformBlocks) && - visitor->Visit("maxDescriptorSetUpdateAfterBindInlineUniformBlocks", &properties->maxDescriptorSetUpdateAfterBindInlineUniformBlocks) && - visitor->Visit("maxInlineUniformTotalSize", &properties->maxInlineUniformTotalSize) && - visitor->Visit("integerDotProduct8BitUnsignedAccelerated", &properties->integerDotProduct8BitUnsignedAccelerated) && - visitor->Visit("integerDotProduct8BitSignedAccelerated", &properties->integerDotProduct8BitSignedAccelerated) && - visitor->Visit("integerDotProduct8BitMixedSignednessAccelerated", &properties->integerDotProduct8BitMixedSignednessAccelerated) && - visitor->Visit("integerDotProduct4x8BitPackedUnsignedAccelerated", &properties->integerDotProduct4x8BitPackedUnsignedAccelerated) && - visitor->Visit("integerDotProduct4x8BitPackedSignedAccelerated", &properties->integerDotProduct4x8BitPackedSignedAccelerated) && - visitor->Visit("integerDotProduct4x8BitPackedMixedSignednessAccelerated", &properties->integerDotProduct4x8BitPackedMixedSignednessAccelerated) && - visitor->Visit("integerDotProduct16BitUnsignedAccelerated", &properties->integerDotProduct16BitUnsignedAccelerated) && - visitor->Visit("integerDotProduct16BitSignedAccelerated", &properties->integerDotProduct16BitSignedAccelerated) && - visitor->Visit("integerDotProduct16BitMixedSignednessAccelerated", &properties->integerDotProduct16BitMixedSignednessAccelerated) && - visitor->Visit("integerDotProduct32BitUnsignedAccelerated", &properties->integerDotProduct32BitUnsignedAccelerated) && - visitor->Visit("integerDotProduct32BitSignedAccelerated", &properties->integerDotProduct32BitSignedAccelerated) && - visitor->Visit("integerDotProduct32BitMixedSignednessAccelerated", &properties->integerDotProduct32BitMixedSignednessAccelerated) && - visitor->Visit("integerDotProduct64BitUnsignedAccelerated", &properties->integerDotProduct64BitUnsignedAccelerated) && - visitor->Visit("integerDotProduct64BitSignedAccelerated", &properties->integerDotProduct64BitSignedAccelerated) && - visitor->Visit("integerDotProduct64BitMixedSignednessAccelerated", &properties->integerDotProduct64BitMixedSignednessAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating8BitUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating8BitUnsignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating8BitSignedAccelerated", &properties->integerDotProductAccumulatingSaturating8BitSignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated", &properties->integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating16BitUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating16BitUnsignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating16BitSignedAccelerated", &properties->integerDotProductAccumulatingSaturating16BitSignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating32BitUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating32BitUnsignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating32BitSignedAccelerated", &properties->integerDotProductAccumulatingSaturating32BitSignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating64BitUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating64BitUnsignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating64BitSignedAccelerated", &properties->integerDotProductAccumulatingSaturating64BitSignedAccelerated) && - visitor->Visit("integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated) && - visitor->Visit("storageTexelBufferOffsetAlignmentBytes", &properties->storageTexelBufferOffsetAlignmentBytes) && - visitor->Visit("storageTexelBufferOffsetSingleTexelAlignment", &properties->storageTexelBufferOffsetSingleTexelAlignment) && - visitor->Visit("uniformTexelBufferOffsetAlignmentBytes", &properties->uniformTexelBufferOffsetAlignmentBytes) && - visitor->Visit("uniformTexelBufferOffsetSingleTexelAlignment", &properties->uniformTexelBufferOffsetSingleTexelAlignment) && - visitor->Visit("maxBufferSize", &properties->maxBufferSize); -} - -template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan13Features* features) { + + visitor->Visit("queueFlags", &properties->queueFlags) && + visitor->Visit("queueCount", &properties->queueCount) && + visitor->Visit("timestampValidBits", &properties->timestampValidBits) && + visitor->Visit("minImageTransferGranularity", + &properties->minImageTransferGranularity); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkExtensionProperties* properties) { return - visitor->Visit("robustImageAccess", &features->robustImageAccess) && - visitor->Visit("inlineUniformBlock", &features->inlineUniformBlock) && - visitor->Visit("descriptorBindingInlineUniformBlockUpdateAfterBind", &features->descriptorBindingInlineUniformBlockUpdateAfterBind) && - visitor->Visit("pipelineCreationCacheControl", &features->pipelineCreationCacheControl) && - visitor->Visit("privateData", &features->privateData) && - visitor->Visit("shaderDemoteToHelperInvocation", &features->shaderDemoteToHelperInvocation) && - visitor->Visit("shaderTerminateInvocation", &features->shaderTerminateInvocation) && - visitor->Visit("subgroupSizeControl", &features->subgroupSizeControl) && - visitor->Visit("computeFullSubgroups", &features->computeFullSubgroups) && - visitor->Visit("synchronization2", &features->synchronization2) && - visitor->Visit("textureCompressionASTC_HDR", &features->textureCompressionASTC_HDR) && - visitor->Visit("shaderZeroInitializeWorkgroupMemory", &features->shaderZeroInitializeWorkgroupMemory) && - visitor->Visit("dynamicRendering", &features->dynamicRendering) && - visitor->Visit("shaderIntegerDotProduct", &features->shaderIntegerDotProduct) && - visitor->Visit("maintenance4", &features->maintenance4); + + visitor->Visit("extensionName", &properties->extensionName) && + visitor->Visit("specVersion", &properties->specVersion); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkJsonCore14* core) { +inline bool Iterate(Visitor* visitor, VkLayerProperties* properties) { return - visitor->Visit("features", &core->features) && - visitor->Visit("properties", &core->properties); + + visitor->Visit("layerName", &properties->layerName) && + visitor->Visit("specVersion", &properties->specVersion) && + visitor->Visit("implementationVersion", + &properties->implementationVersion) && + visitor->Visit("description", &properties->description); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan14Properties* properties) { +inline bool Iterate(Visitor* visitor, VkFormatProperties* properties) { return - visitor->Visit("lineSubPixelPrecisionBits", &properties->lineSubPixelPrecisionBits) && - visitor->Visit("maxVertexAttribDivisor", &properties->maxVertexAttribDivisor) && - visitor->Visit("supportsNonZeroFirstInstance", &properties->supportsNonZeroFirstInstance) && - visitor->Visit("maxPushDescriptors", &properties->maxPushDescriptors) && - visitor->Visit("dynamicRenderingLocalReadDepthStencilAttachments", &properties->dynamicRenderingLocalReadDepthStencilAttachments) && - visitor->Visit("dynamicRenderingLocalReadMultisampledAttachments", &properties->dynamicRenderingLocalReadMultisampledAttachments) && - visitor->Visit("earlyFragmentMultisampleCoverageAfterSampleCounting", &properties->earlyFragmentMultisampleCoverageAfterSampleCounting) && - visitor->Visit("earlyFragmentSampleMaskTestBeforeSampleCounting", &properties->earlyFragmentSampleMaskTestBeforeSampleCounting) && - visitor->Visit("depthStencilSwizzleOneSupport", &properties->depthStencilSwizzleOneSupport) && - visitor->Visit("polygonModePointSize", &properties->polygonModePointSize) && - visitor->Visit("nonStrictSinglePixelWideLinesUseParallelogram", &properties->nonStrictSinglePixelWideLinesUseParallelogram) && - visitor->Visit("nonStrictWideLinesUseParallelogram", &properties->nonStrictWideLinesUseParallelogram) && - visitor->Visit("blockTexelViewCompatibleMultipleLayers", &properties->blockTexelViewCompatibleMultipleLayers) && - visitor->Visit("maxCombinedImageSamplerDescriptorCount", &properties->maxCombinedImageSamplerDescriptorCount) && - visitor->Visit("fragmentShadingRateClampCombinerInputs", &properties->fragmentShadingRateClampCombinerInputs) && - visitor->Visit("defaultRobustnessStorageBuffers", &properties->defaultRobustnessStorageBuffers) && - visitor->Visit("defaultRobustnessUniformBuffers", &properties->defaultRobustnessUniformBuffers) && - visitor->Visit("defaultRobustnessVertexInputs", &properties->defaultRobustnessVertexInputs) && - visitor->Visit("defaultRobustnessImages", &properties->defaultRobustnessImages) && - visitor->Visit("copySrcLayoutCount", &properties->copySrcLayoutCount) && - visitor->VisitArray("pCopySrcLayouts", properties->copySrcLayoutCount, &properties->pCopySrcLayouts) && - visitor->Visit("copyDstLayoutCount", &properties->copyDstLayoutCount) && - visitor->VisitArray("pCopyDstLayouts", properties->copyDstLayoutCount, &properties->pCopyDstLayouts) && - visitor->Visit("optimalTilingLayoutUUID", &properties->optimalTilingLayoutUUID) && - visitor->Visit("identicalMemoryTypeRequirements", &properties->identicalMemoryTypeRequirements); -} - -template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan14Features* features) { + + visitor->Visit("linearTilingFeatures", + &properties->linearTilingFeatures) && + visitor->Visit("optimalTilingFeatures", + &properties->optimalTilingFeatures) && + visitor->Visit("bufferFeatures", &properties->bufferFeatures); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceVariablePointersFeatures* features) { return - visitor->Visit("globalPriorityQuery", &features->globalPriorityQuery) && - visitor->Visit("shaderSubgroupRotate", &features->shaderSubgroupRotate) && - visitor->Visit("shaderSubgroupRotateClustered", &features->shaderSubgroupRotateClustered) && - visitor->Visit("shaderFloatControls2", &features->shaderFloatControls2) && - visitor->Visit("shaderExpectAssume", &features->shaderExpectAssume) && - visitor->Visit("rectangularLines", &features->rectangularLines) && - visitor->Visit("bresenhamLines", &features->bresenhamLines) && - visitor->Visit("smoothLines", &features->smoothLines) && - visitor->Visit("stippledRectangularLines", &features->stippledRectangularLines) && - visitor->Visit("stippledBresenhamLines", &features->stippledBresenhamLines) && - visitor->Visit("stippledSmoothLines", &features->stippledSmoothLines) && - visitor->Visit("vertexAttributeInstanceRateDivisor", &features->vertexAttributeInstanceRateDivisor) && - visitor->Visit("vertexAttributeInstanceRateZeroDivisor", &features->vertexAttributeInstanceRateZeroDivisor) && - visitor->Visit("indexTypeUint8", &features->indexTypeUint8) && - visitor->Visit("dynamicRenderingLocalRead", &features->dynamicRenderingLocalRead) && - visitor->Visit("maintenance5", &features->maintenance5) && - visitor->Visit("maintenance6", &features->maintenance6) && - visitor->Visit("pipelineProtectedAccess", &features->pipelineProtectedAccess) && - visitor->Visit("pipelineRobustness", &features->pipelineRobustness) && - visitor->Visit("hostImageCopy", &features->hostImageCopy); -} -// clang-format on + + visitor->Visit("variablePointersStorageBuffer", + &features->variablePointersStorageBuffer) && + visitor->Visit("variablePointers", &features->variablePointers); +} template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkJsonExtDriverProperties* properties) { - return visitor->Visit("driverPropertiesKHR", - &properties->driver_properties_khr); + VkPhysicalDeviceShaderFloat16Int8Features* features) { + return + + visitor->Visit("shaderFloat16", &features->shaderFloat16) && + visitor->Visit("shaderInt8", &features->shaderInt8); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceDriverPropertiesKHR* properties) { - return visitor->Visit("driverID", &properties->driverID) && - visitor->Visit("driverName", &properties->driverName) && - visitor->Visit("driverInfo", &properties->driverInfo) && - visitor->Visit("conformanceVersion", &properties->conformanceVersion); + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT* features) { + return + + visitor->Visit("image2DViewOf3D", &features->image2DViewOf3D) && + visitor->Visit("sampler2DViewOf3D", &features->sampler2DViewOf3D); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkConformanceVersionKHR* version) { - return visitor->Visit("major", &version->major) && - visitor->Visit("minor", &version->minor) && - visitor->Visit("subminor", &version->subminor) && - visitor->Visit("patch", &version->patch); + VkPhysicalDeviceCustomBorderColorFeaturesEXT* features) { + return + + visitor->Visit("customBorderColors", &features->customBorderColors) && + visitor->Visit("customBorderColorWithoutFormat", + &features->customBorderColorWithoutFormat); +} + +template <typename Visitor> +inline bool Iterate( + Visitor* visitor, + VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT* features) { + return + + visitor->Visit("primitiveTopologyListRestart", + &features->primitiveTopologyListRestart) && + visitor->Visit("primitiveTopologyPatchListRestart", + &features->primitiveTopologyPatchListRestart); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkJsonExtVariablePointerFeatures* features) { - return visitor->Visit("variablePointerFeaturesKHR", - &features->variable_pointer_features_khr); + VkPhysicalDeviceProvokingVertexFeaturesEXT* features) { + return + + visitor->Visit("provokingVertexLast", &features->provokingVertexLast) && + visitor->Visit("transformFeedbackPreservesProvokingVertex", + &features->transformFeedbackPreservesProvokingVertex); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkJsonExtShaderFloat16Int8Features* features) { - return visitor->Visit("shaderFloat16Int8FeaturesKHR", - &features->shader_float16_int8_features_khr); + VkPhysicalDeviceIndexTypeUint8Features* features) { + return + + visitor->Visit("indexTypeUint8", &features->indexTypeUint8); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkMemoryType* type) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceVertexAttributeDivisorFeatures* features) { return - visitor->Visit("propertyFlags", &type->propertyFlags) && - visitor->Visit("heapIndex", &type->heapIndex); + + visitor->Visit("vertexAttributeInstanceRateDivisor", + &features->vertexAttributeInstanceRateDivisor) && + visitor->Visit("vertexAttributeInstanceRateZeroDivisor", + &features->vertexAttributeInstanceRateZeroDivisor); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkMemoryHeap* heap) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceTransformFeedbackFeaturesEXT* features) { return - visitor->Visit("size", &heap->size) && - visitor->Visit("flags", &heap->flags); + + visitor->Visit("transformFeedback", &features->transformFeedback) && + visitor->Visit("geometryStreams", &features->geometryStreams); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkPhysicalDeviceMemoryProperties* properties) { +inline bool Iterate( + Visitor* visitor, + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR* features) { return - visitor->Visit("memoryTypeCount", &properties->memoryTypeCount) && - visitor->VisitArray("memoryTypes", properties->memoryTypeCount, &properties->memoryTypes) && - visitor->Visit("memoryHeapCount", &properties->memoryHeapCount) && - visitor->VisitArray("memoryHeaps", properties->memoryHeapCount, &properties->memoryHeaps); + + visitor->Visit("shaderSubgroupUniformControlFlow", + &features->shaderSubgroupUniformControlFlow); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceSubgroupProperties* properties) { - return visitor->Visit("subgroupSize", &properties->subgroupSize) && - visitor->Visit("supportedStages", &properties->supportedStages) && - visitor->Visit("supportedOperations", - &properties->supportedOperations) && - visitor->Visit("quadOperationsInAllStages", - &properties->quadOperationsInAllStages); +inline bool Iterate( + Visitor* visitor, + VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures* features) { + return + + visitor->Visit("shaderSubgroupExtendedTypes", + &features->shaderSubgroupExtendedTypes); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDevicePointClippingProperties* properties) { - return visitor->Visit("pointClippingBehavior", - &properties->pointClippingBehavior); + VkPhysicalDevice8BitStorageFeatures* features) { + return + + visitor->Visit("storageBuffer8BitAccess", + &features->storageBuffer8BitAccess) && + visitor->Visit("uniformAndStorageBuffer8BitAccess", + &features->uniformAndStorageBuffer8BitAccess) && + visitor->Visit("storagePushConstant8", &features->storagePushConstant8); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceMultiviewProperties* properties) { - return visitor->Visit("maxMultiviewViewCount", - &properties->maxMultiviewViewCount) && - visitor->Visit("maxMultiviewInstanceIndex", - &properties->maxMultiviewInstanceIndex); + VkPhysicalDeviceShaderIntegerDotProductFeatures* features) { + return + + visitor->Visit("shaderIntegerDotProduct", + &features->shaderIntegerDotProduct); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceIDProperties* properties) { - return visitor->Visit("deviceUUID", &properties->deviceUUID) && - visitor->Visit("driverUUID", &properties->driverUUID) && - visitor->Visit("deviceLUID", &properties->deviceLUID) && - visitor->Visit("deviceNodeMask", &properties->deviceNodeMask) && - visitor->Visit("deviceLUIDValid", &properties->deviceLUIDValid); +inline bool Iterate( + Visitor* visitor, + VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG* features) { + return + + visitor->Visit("relaxedLineRasterization", + &features->relaxedLineRasterization); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceMaintenance3Properties* properties) { - return visitor->Visit("maxPerSetDescriptors", - &properties->maxPerSetDescriptors) && - visitor->Visit("maxMemoryAllocationSize", - &properties->maxMemoryAllocationSize); + VkPhysicalDeviceLineRasterizationFeatures* features) { + return + + visitor->Visit("rectangularLines", &features->rectangularLines) && + visitor->Visit("bresenhamLines", &features->bresenhamLines) && + visitor->Visit("smoothLines", &features->smoothLines) && + visitor->Visit("stippledRectangularLines", + &features->stippledRectangularLines) && + visitor->Visit("stippledBresenhamLines", + &features->stippledBresenhamLines) && + visitor->Visit("stippledSmoothLines", &features->stippledSmoothLines); +} + +template <typename Visitor> +inline bool Iterate( + Visitor* visitor, + VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT* features) { + return + + visitor->Visit("primitivesGeneratedQuery", + &features->primitivesGeneratedQuery) && + visitor->Visit( + "primitivesGeneratedQueryWithRasterizerDiscard", + &features->primitivesGeneratedQueryWithRasterizerDiscard) && + visitor->Visit("primitivesGeneratedQueryWithNonZeroStreams", + &features->primitivesGeneratedQueryWithNonZeroStreams); } template <typename Visitor> inline bool Iterate(Visitor* visitor, VkPhysicalDevice16BitStorageFeatures* features) { - return visitor->Visit("storageBuffer16BitAccess", - &features->storageBuffer16BitAccess) && - visitor->Visit("uniformAndStorageBuffer16BitAccess", - &features->uniformAndStorageBuffer16BitAccess) && - visitor->Visit("storagePushConstant16", - &features->storagePushConstant16) && - visitor->Visit("storageInputOutput16", - &features->storageInputOutput16); + return + + visitor->Visit("storageBuffer16BitAccess", + &features->storageBuffer16BitAccess) && + visitor->Visit("uniformAndStorageBuffer16BitAccess", + &features->uniformAndStorageBuffer16BitAccess) && + visitor->Visit("storagePushConstant16", + &features->storagePushConstant16) && + visitor->Visit("storageInputOutput16", &features->storageInputOutput16); } template <typename Visitor> inline bool Iterate(Visitor* visitor, VkPhysicalDeviceMultiviewFeatures* features) { - return visitor->Visit("multiview", &features->multiview) && - visitor->Visit("multiviewGeometryShader", - &features->multiviewGeometryShader) && - visitor->Visit("multiviewTessellationShader", - &features->multiviewTessellationShader); + return + + visitor->Visit("multiview", &features->multiview) && + visitor->Visit("multiviewGeometryShader", + &features->multiviewGeometryShader) && + visitor->Visit("multiviewTessellationShader", + &features->multiviewTessellationShader); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceVariablePointerFeatures* features) { - return visitor->Visit("variablePointersStorageBuffer", - &features->variablePointersStorageBuffer) && - visitor->Visit("variablePointers", &features->variablePointers); + VkPhysicalDeviceProtectedMemoryFeatures* features) { + return + + visitor->Visit("protectedMemory", &features->protectedMemory); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceShaderFloat16Int8FeaturesKHR* features) { - return visitor->Visit("shaderFloat16", &features->shaderFloat16) && - visitor->Visit("shaderInt8", &features->shaderInt8); + VkPhysicalDeviceSamplerYcbcrConversionFeatures* features) { + return + + visitor->Visit("samplerYcbcrConversion", + &features->samplerYcbcrConversion); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceProtectedMemoryFeatures* features) { - return visitor->Visit("protectedMemory", &features->protectedMemory); + VkPhysicalDeviceShaderDrawParameterFeatures* features) { + return + + visitor->Visit("shaderDrawParameters", &features->shaderDrawParameters); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkPhysicalDeviceLimits* limits) { + return + + visitor->Visit("maxImageDimension1D", &limits->maxImageDimension1D) && + visitor->Visit("maxImageDimension2D", &limits->maxImageDimension2D) && + visitor->Visit("maxImageDimension3D", &limits->maxImageDimension3D) && + visitor->Visit("maxImageDimensionCube", &limits->maxImageDimensionCube) && + visitor->Visit("maxImageArrayLayers", &limits->maxImageArrayLayers) && + visitor->Visit("maxTexelBufferElements", + &limits->maxTexelBufferElements) && + visitor->Visit("maxUniformBufferRange", &limits->maxUniformBufferRange) && + visitor->Visit("maxStorageBufferRange", &limits->maxStorageBufferRange) && + visitor->Visit("maxPushConstantsSize", &limits->maxPushConstantsSize) && + visitor->Visit("maxMemoryAllocationCount", + &limits->maxMemoryAllocationCount) && + visitor->Visit("maxSamplerAllocationCount", + &limits->maxSamplerAllocationCount) && + visitor->Visit("bufferImageGranularity", + &limits->bufferImageGranularity) && + visitor->Visit("sparseAddressSpaceSize", + &limits->sparseAddressSpaceSize) && + visitor->Visit("maxBoundDescriptorSets", + &limits->maxBoundDescriptorSets) && + visitor->Visit("maxPerStageDescriptorSamplers", + &limits->maxPerStageDescriptorSamplers) && + visitor->Visit("maxPerStageDescriptorUniformBuffers", + &limits->maxPerStageDescriptorUniformBuffers) && + visitor->Visit("maxPerStageDescriptorStorageBuffers", + &limits->maxPerStageDescriptorStorageBuffers) && + visitor->Visit("maxPerStageDescriptorSampledImages", + &limits->maxPerStageDescriptorSampledImages) && + visitor->Visit("maxPerStageDescriptorStorageImages", + &limits->maxPerStageDescriptorStorageImages) && + visitor->Visit("maxPerStageDescriptorInputAttachments", + &limits->maxPerStageDescriptorInputAttachments) && + visitor->Visit("maxPerStageResources", &limits->maxPerStageResources) && + visitor->Visit("maxDescriptorSetSamplers", + &limits->maxDescriptorSetSamplers) && + visitor->Visit("maxDescriptorSetUniformBuffers", + &limits->maxDescriptorSetUniformBuffers) && + visitor->Visit("maxDescriptorSetUniformBuffersDynamic", + &limits->maxDescriptorSetUniformBuffersDynamic) && + visitor->Visit("maxDescriptorSetStorageBuffers", + &limits->maxDescriptorSetStorageBuffers) && + visitor->Visit("maxDescriptorSetStorageBuffersDynamic", + &limits->maxDescriptorSetStorageBuffersDynamic) && + visitor->Visit("maxDescriptorSetSampledImages", + &limits->maxDescriptorSetSampledImages) && + visitor->Visit("maxDescriptorSetStorageImages", + &limits->maxDescriptorSetStorageImages) && + visitor->Visit("maxDescriptorSetInputAttachments", + &limits->maxDescriptorSetInputAttachments) && + visitor->Visit("maxVertexInputAttributes", + &limits->maxVertexInputAttributes) && + visitor->Visit("maxVertexInputBindings", + &limits->maxVertexInputBindings) && + visitor->Visit("maxVertexInputAttributeOffset", + &limits->maxVertexInputAttributeOffset) && + visitor->Visit("maxVertexInputBindingStride", + &limits->maxVertexInputBindingStride) && + visitor->Visit("maxVertexOutputComponents", + &limits->maxVertexOutputComponents) && + visitor->Visit("maxTessellationGenerationLevel", + &limits->maxTessellationGenerationLevel) && + visitor->Visit("maxTessellationPatchSize", + &limits->maxTessellationPatchSize) && + visitor->Visit("maxTessellationControlPerVertexInputComponents", + &limits->maxTessellationControlPerVertexInputComponents) && + visitor->Visit( + "maxTessellationControlPerVertexOutputComponents", + &limits->maxTessellationControlPerVertexOutputComponents) && + visitor->Visit("maxTessellationControlPerPatchOutputComponents", + &limits->maxTessellationControlPerPatchOutputComponents) && + visitor->Visit("maxTessellationControlTotalOutputComponents", + &limits->maxTessellationControlTotalOutputComponents) && + visitor->Visit("maxTessellationEvaluationInputComponents", + &limits->maxTessellationEvaluationInputComponents) && + visitor->Visit("maxTessellationEvaluationOutputComponents", + &limits->maxTessellationEvaluationOutputComponents) && + visitor->Visit("maxGeometryShaderInvocations", + &limits->maxGeometryShaderInvocations) && + visitor->Visit("maxGeometryInputComponents", + &limits->maxGeometryInputComponents) && + visitor->Visit("maxGeometryOutputComponents", + &limits->maxGeometryOutputComponents) && + visitor->Visit("maxGeometryOutputVertices", + &limits->maxGeometryOutputVertices) && + visitor->Visit("maxGeometryTotalOutputComponents", + &limits->maxGeometryTotalOutputComponents) && + visitor->Visit("maxFragmentInputComponents", + &limits->maxFragmentInputComponents) && + visitor->Visit("maxFragmentOutputAttachments", + &limits->maxFragmentOutputAttachments) && + visitor->Visit("maxFragmentDualSrcAttachments", + &limits->maxFragmentDualSrcAttachments) && + visitor->Visit("maxFragmentCombinedOutputResources", + &limits->maxFragmentCombinedOutputResources) && + visitor->Visit("maxComputeSharedMemorySize", + &limits->maxComputeSharedMemorySize) && + visitor->Visit("maxComputeWorkGroupCount", + &limits->maxComputeWorkGroupCount) && + visitor->Visit("maxComputeWorkGroupInvocations", + &limits->maxComputeWorkGroupInvocations) && + visitor->Visit("maxComputeWorkGroupSize", + &limits->maxComputeWorkGroupSize) && + visitor->Visit("subPixelPrecisionBits", &limits->subPixelPrecisionBits) && + visitor->Visit("subTexelPrecisionBits", &limits->subTexelPrecisionBits) && + visitor->Visit("mipmapPrecisionBits", &limits->mipmapPrecisionBits) && + visitor->Visit("maxDrawIndexedIndexValue", + &limits->maxDrawIndexedIndexValue) && + visitor->Visit("maxDrawIndirectCount", &limits->maxDrawIndirectCount) && + visitor->Visit("maxSamplerLodBias", &limits->maxSamplerLodBias) && + visitor->Visit("maxSamplerAnisotropy", &limits->maxSamplerAnisotropy) && + visitor->Visit("maxViewports", &limits->maxViewports) && + visitor->Visit("maxViewportDimensions", &limits->maxViewportDimensions) && + visitor->Visit("viewportBoundsRange", &limits->viewportBoundsRange) && + visitor->Visit("viewportSubPixelBits", &limits->viewportSubPixelBits) && + visitor->Visit("minMemoryMapAlignment", &limits->minMemoryMapAlignment) && + visitor->Visit("minTexelBufferOffsetAlignment", + &limits->minTexelBufferOffsetAlignment) && + visitor->Visit("minUniformBufferOffsetAlignment", + &limits->minUniformBufferOffsetAlignment) && + visitor->Visit("minStorageBufferOffsetAlignment", + &limits->minStorageBufferOffsetAlignment) && + visitor->Visit("minTexelOffset", &limits->minTexelOffset) && + visitor->Visit("maxTexelOffset", &limits->maxTexelOffset) && + visitor->Visit("minTexelGatherOffset", &limits->minTexelGatherOffset) && + visitor->Visit("maxTexelGatherOffset", &limits->maxTexelGatherOffset) && + visitor->Visit("minInterpolationOffset", + &limits->minInterpolationOffset) && + visitor->Visit("maxInterpolationOffset", + &limits->maxInterpolationOffset) && + visitor->Visit("subPixelInterpolationOffsetBits", + &limits->subPixelInterpolationOffsetBits) && + visitor->Visit("maxFramebufferWidth", &limits->maxFramebufferWidth) && + visitor->Visit("maxFramebufferHeight", &limits->maxFramebufferHeight) && + visitor->Visit("maxFramebufferLayers", &limits->maxFramebufferLayers) && + visitor->Visit("framebufferColorSampleCounts", + &limits->framebufferColorSampleCounts) && + visitor->Visit("framebufferDepthSampleCounts", + &limits->framebufferDepthSampleCounts) && + visitor->Visit("framebufferStencilSampleCounts", + &limits->framebufferStencilSampleCounts) && + visitor->Visit("framebufferNoAttachmentsSampleCounts", + &limits->framebufferNoAttachmentsSampleCounts) && + visitor->Visit("maxColorAttachments", &limits->maxColorAttachments) && + visitor->Visit("sampledImageColorSampleCounts", + &limits->sampledImageColorSampleCounts) && + visitor->Visit("sampledImageIntegerSampleCounts", + &limits->sampledImageIntegerSampleCounts) && + visitor->Visit("sampledImageDepthSampleCounts", + &limits->sampledImageDepthSampleCounts) && + visitor->Visit("sampledImageStencilSampleCounts", + &limits->sampledImageStencilSampleCounts) && + visitor->Visit("storageImageSampleCounts", + &limits->storageImageSampleCounts) && + visitor->Visit("maxSampleMaskWords", &limits->maxSampleMaskWords) && + visitor->Visit("timestampComputeAndGraphics", + &limits->timestampComputeAndGraphics) && + visitor->Visit("timestampPeriod", &limits->timestampPeriod) && + visitor->Visit("maxClipDistances", &limits->maxClipDistances) && + visitor->Visit("maxCullDistances", &limits->maxCullDistances) && + visitor->Visit("maxCombinedClipAndCullDistances", + &limits->maxCombinedClipAndCullDistances) && + visitor->Visit("discreteQueuePriorities", + &limits->discreteQueuePriorities) && + visitor->Visit("pointSizeRange", &limits->pointSizeRange) && + visitor->Visit("lineWidthRange", &limits->lineWidthRange) && + visitor->Visit("pointSizeGranularity", &limits->pointSizeGranularity) && + visitor->Visit("lineWidthGranularity", &limits->lineWidthGranularity) && + visitor->Visit("strictLines", &limits->strictLines) && + visitor->Visit("standardSampleLocations", + &limits->standardSampleLocations) && + visitor->Visit("optimalBufferCopyOffsetAlignment", + &limits->optimalBufferCopyOffsetAlignment) && + visitor->Visit("optimalBufferCopyRowPitchAlignment", + &limits->optimalBufferCopyRowPitchAlignment) && + visitor->Visit("nonCoherentAtomSize", &limits->nonCoherentAtomSize); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkPhysicalDeviceFeatures* features) { + return + + visitor->Visit("robustBufferAccess", &features->robustBufferAccess) && + visitor->Visit("fullDrawIndexUint32", &features->fullDrawIndexUint32) && + visitor->Visit("imageCubeArray", &features->imageCubeArray) && + visitor->Visit("independentBlend", &features->independentBlend) && + visitor->Visit("geometryShader", &features->geometryShader) && + visitor->Visit("tessellationShader", &features->tessellationShader) && + visitor->Visit("sampleRateShading", &features->sampleRateShading) && + visitor->Visit("dualSrcBlend", &features->dualSrcBlend) && + visitor->Visit("logicOp", &features->logicOp) && + visitor->Visit("multiDrawIndirect", &features->multiDrawIndirect) && + visitor->Visit("drawIndirectFirstInstance", + &features->drawIndirectFirstInstance) && + visitor->Visit("depthClamp", &features->depthClamp) && + visitor->Visit("depthBiasClamp", &features->depthBiasClamp) && + visitor->Visit("fillModeNonSolid", &features->fillModeNonSolid) && + visitor->Visit("depthBounds", &features->depthBounds) && + visitor->Visit("wideLines", &features->wideLines) && + visitor->Visit("largePoints", &features->largePoints) && + visitor->Visit("alphaToOne", &features->alphaToOne) && + visitor->Visit("multiViewport", &features->multiViewport) && + visitor->Visit("samplerAnisotropy", &features->samplerAnisotropy) && + visitor->Visit("textureCompressionETC2", + &features->textureCompressionETC2) && + visitor->Visit("textureCompressionASTC_LDR", + &features->textureCompressionASTC_LDR) && + visitor->Visit("textureCompressionBC", &features->textureCompressionBC) && + visitor->Visit("occlusionQueryPrecise", + &features->occlusionQueryPrecise) && + visitor->Visit("pipelineStatisticsQuery", + &features->pipelineStatisticsQuery) && + visitor->Visit("vertexPipelineStoresAndAtomics", + &features->vertexPipelineStoresAndAtomics) && + visitor->Visit("fragmentStoresAndAtomics", + &features->fragmentStoresAndAtomics) && + visitor->Visit("shaderTessellationAndGeometryPointSize", + &features->shaderTessellationAndGeometryPointSize) && + visitor->Visit("shaderImageGatherExtended", + &features->shaderImageGatherExtended) && + visitor->Visit("shaderStorageImageExtendedFormats", + &features->shaderStorageImageExtendedFormats) && + visitor->Visit("shaderStorageImageMultisample", + &features->shaderStorageImageMultisample) && + visitor->Visit("shaderStorageImageReadWithoutFormat", + &features->shaderStorageImageReadWithoutFormat) && + visitor->Visit("shaderStorageImageWriteWithoutFormat", + &features->shaderStorageImageWriteWithoutFormat) && + visitor->Visit("shaderUniformBufferArrayDynamicIndexing", + &features->shaderUniformBufferArrayDynamicIndexing) && + visitor->Visit("shaderSampledImageArrayDynamicIndexing", + &features->shaderSampledImageArrayDynamicIndexing) && + visitor->Visit("shaderStorageBufferArrayDynamicIndexing", + &features->shaderStorageBufferArrayDynamicIndexing) && + visitor->Visit("shaderStorageImageArrayDynamicIndexing", + &features->shaderStorageImageArrayDynamicIndexing) && + visitor->Visit("shaderClipDistance", &features->shaderClipDistance) && + visitor->Visit("shaderCullDistance", &features->shaderCullDistance) && + visitor->Visit("shaderFloat64", &features->shaderFloat64) && + visitor->Visit("shaderInt64", &features->shaderInt64) && + visitor->Visit("shaderInt16", &features->shaderInt16) && + visitor->Visit("shaderResourceResidency", + &features->shaderResourceResidency) && + visitor->Visit("shaderResourceMinLod", &features->shaderResourceMinLod) && + visitor->Visit("sparseBinding", &features->sparseBinding) && + visitor->Visit("sparseResidencyBuffer", + &features->sparseResidencyBuffer) && + visitor->Visit("sparseResidencyImage2D", + &features->sparseResidencyImage2D) && + visitor->Visit("sparseResidencyImage3D", + &features->sparseResidencyImage3D) && + visitor->Visit("sparseResidency2Samples", + &features->sparseResidency2Samples) && + visitor->Visit("sparseResidency4Samples", + &features->sparseResidency4Samples) && + visitor->Visit("sparseResidency8Samples", + &features->sparseResidency8Samples) && + visitor->Visit("sparseResidency16Samples", + &features->sparseResidency16Samples) && + visitor->Visit("sparseResidencyAliased", + &features->sparseResidencyAliased) && + visitor->Visit("variableMultisampleRate", + &features->variableMultisampleRate) && + visitor->Visit("inheritedQueries", &features->inheritedQueries); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceSamplerYcbcrConversionFeatures* features) { - return visitor->Visit("samplerYcbcrConversion", - &features->samplerYcbcrConversion); + VkPhysicalDeviceVulkan11Properties* properties) { + return + + visitor->Visit("deviceUUID", &properties->deviceUUID) && + visitor->Visit("driverUUID", &properties->driverUUID) && + visitor->Visit("deviceLUID", &properties->deviceLUID) && + visitor->Visit("deviceNodeMask", &properties->deviceNodeMask) && + visitor->Visit("deviceLUIDValid", &properties->deviceLUIDValid) && + visitor->Visit("subgroupSize", &properties->subgroupSize) && + visitor->Visit("subgroupSupportedStages", + &properties->subgroupSupportedStages) && + visitor->Visit("subgroupSupportedOperations", + &properties->subgroupSupportedOperations) && + visitor->Visit("subgroupQuadOperationsInAllStages", + &properties->subgroupQuadOperationsInAllStages) && + visitor->Visit("pointClippingBehavior", + &properties->pointClippingBehavior) && + visitor->Visit("maxMultiviewViewCount", + &properties->maxMultiviewViewCount) && + visitor->Visit("maxMultiviewInstanceIndex", + &properties->maxMultiviewInstanceIndex) && + visitor->Visit("protectedNoFault", &properties->protectedNoFault) && + visitor->Visit("maxPerSetDescriptors", + &properties->maxPerSetDescriptors) && + visitor->Visit("maxMemoryAllocationSize", + &properties->maxMemoryAllocationSize); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkPhysicalDeviceShaderDrawParameterFeatures* features) { - return visitor->Visit("shaderDrawParameters", - &features->shaderDrawParameters); + VkPhysicalDeviceVulkan11Features* features) { + return + + visitor->Visit("storageBuffer16BitAccess", + &features->storageBuffer16BitAccess) && + visitor->Visit("uniformAndStorageBuffer16BitAccess", + &features->uniformAndStorageBuffer16BitAccess) && + visitor->Visit("storagePushConstant16", + &features->storagePushConstant16) && + visitor->Visit("storageInputOutput16", &features->storageInputOutput16) && + visitor->Visit("multiview", &features->multiview) && + visitor->Visit("multiviewGeometryShader", + &features->multiviewGeometryShader) && + visitor->Visit("multiviewTessellationShader", + &features->multiviewTessellationShader) && + visitor->Visit("variablePointersStorageBuffer", + &features->variablePointersStorageBuffer) && + visitor->Visit("variablePointers", &features->variablePointers) && + visitor->Visit("protectedMemory", &features->protectedMemory) && + visitor->Visit("samplerYcbcrConversion", + &features->samplerYcbcrConversion) && + visitor->Visit("shaderDrawParameters", &features->shaderDrawParameters); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkExternalFenceProperties* properties) { - return visitor->Visit("exportFromImportedHandleTypes", - &properties->exportFromImportedHandleTypes) && - visitor->Visit("compatibleHandleTypes", - &properties->compatibleHandleTypes) && - visitor->Visit("externalFenceFeatures", - &properties->externalFenceFeatures); +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceVulkan12Properties* properties) { + return + + visitor->Visit("driverID", &properties->driverID) && + visitor->Visit("driverName", &properties->driverName) && + visitor->Visit("driverInfo", &properties->driverInfo) && + visitor->Visit("conformanceVersion", &properties->conformanceVersion) && + visitor->Visit("denormBehaviorIndependence", + &properties->denormBehaviorIndependence) && + visitor->Visit("roundingModeIndependence", + &properties->roundingModeIndependence) && + visitor->Visit("shaderSignedZeroInfNanPreserveFloat16", + &properties->shaderSignedZeroInfNanPreserveFloat16) && + visitor->Visit("shaderSignedZeroInfNanPreserveFloat32", + &properties->shaderSignedZeroInfNanPreserveFloat32) && + visitor->Visit("shaderSignedZeroInfNanPreserveFloat64", + &properties->shaderSignedZeroInfNanPreserveFloat64) && + visitor->Visit("shaderDenormPreserveFloat16", + &properties->shaderDenormPreserveFloat16) && + visitor->Visit("shaderDenormPreserveFloat32", + &properties->shaderDenormPreserveFloat32) && + visitor->Visit("shaderDenormPreserveFloat64", + &properties->shaderDenormPreserveFloat64) && + visitor->Visit("shaderDenormFlushToZeroFloat16", + &properties->shaderDenormFlushToZeroFloat16) && + visitor->Visit("shaderDenormFlushToZeroFloat32", + &properties->shaderDenormFlushToZeroFloat32) && + visitor->Visit("shaderDenormFlushToZeroFloat64", + &properties->shaderDenormFlushToZeroFloat64) && + visitor->Visit("shaderRoundingModeRTEFloat16", + &properties->shaderRoundingModeRTEFloat16) && + visitor->Visit("shaderRoundingModeRTEFloat32", + &properties->shaderRoundingModeRTEFloat32) && + visitor->Visit("shaderRoundingModeRTEFloat64", + &properties->shaderRoundingModeRTEFloat64) && + visitor->Visit("shaderRoundingModeRTZFloat16", + &properties->shaderRoundingModeRTZFloat16) && + visitor->Visit("shaderRoundingModeRTZFloat32", + &properties->shaderRoundingModeRTZFloat32) && + visitor->Visit("shaderRoundingModeRTZFloat64", + &properties->shaderRoundingModeRTZFloat64) && + visitor->Visit("maxUpdateAfterBindDescriptorsInAllPools", + &properties->maxUpdateAfterBindDescriptorsInAllPools) && + visitor->Visit( + "shaderUniformBufferArrayNonUniformIndexingNative", + &properties->shaderUniformBufferArrayNonUniformIndexingNative) && + visitor->Visit( + "shaderSampledImageArrayNonUniformIndexingNative", + &properties->shaderSampledImageArrayNonUniformIndexingNative) && + visitor->Visit( + "shaderStorageBufferArrayNonUniformIndexingNative", + &properties->shaderStorageBufferArrayNonUniformIndexingNative) && + visitor->Visit( + "shaderStorageImageArrayNonUniformIndexingNative", + &properties->shaderStorageImageArrayNonUniformIndexingNative) && + visitor->Visit( + "shaderInputAttachmentArrayNonUniformIndexingNative", + &properties->shaderInputAttachmentArrayNonUniformIndexingNative) && + visitor->Visit("robustBufferAccessUpdateAfterBind", + &properties->robustBufferAccessUpdateAfterBind) && + visitor->Visit("quadDivergentImplicitLod", + &properties->quadDivergentImplicitLod) && + visitor->Visit( + "maxPerStageDescriptorUpdateAfterBindSamplers", + &properties->maxPerStageDescriptorUpdateAfterBindSamplers) && + visitor->Visit( + "maxPerStageDescriptorUpdateAfterBindUniformBuffers", + &properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers) && + visitor->Visit( + "maxPerStageDescriptorUpdateAfterBindStorageBuffers", + &properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers) && + visitor->Visit( + "maxPerStageDescriptorUpdateAfterBindSampledImages", + &properties->maxPerStageDescriptorUpdateAfterBindSampledImages) && + visitor->Visit( + "maxPerStageDescriptorUpdateAfterBindStorageImages", + &properties->maxPerStageDescriptorUpdateAfterBindStorageImages) && + visitor->Visit( + "maxPerStageDescriptorUpdateAfterBindInputAttachments", + &properties->maxPerStageDescriptorUpdateAfterBindInputAttachments) && + visitor->Visit("maxPerStageUpdateAfterBindResources", + &properties->maxPerStageUpdateAfterBindResources) && + visitor->Visit("maxDescriptorSetUpdateAfterBindSamplers", + &properties->maxDescriptorSetUpdateAfterBindSamplers) && + visitor->Visit( + "maxDescriptorSetUpdateAfterBindUniformBuffers", + &properties->maxDescriptorSetUpdateAfterBindUniformBuffers) && + visitor->Visit( + "maxDescriptorSetUpdateAfterBindUniformBuffersDynamic", + &properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic) && + visitor->Visit( + "maxDescriptorSetUpdateAfterBindStorageBuffers", + &properties->maxDescriptorSetUpdateAfterBindStorageBuffers) && + visitor->Visit( + "maxDescriptorSetUpdateAfterBindStorageBuffersDynamic", + &properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic) && + visitor->Visit( + "maxDescriptorSetUpdateAfterBindSampledImages", + &properties->maxDescriptorSetUpdateAfterBindSampledImages) && + visitor->Visit( + "maxDescriptorSetUpdateAfterBindStorageImages", + &properties->maxDescriptorSetUpdateAfterBindStorageImages) && + visitor->Visit( + "maxDescriptorSetUpdateAfterBindInputAttachments", + &properties->maxDescriptorSetUpdateAfterBindInputAttachments) && + visitor->Visit("supportedDepthResolveModes", + &properties->supportedDepthResolveModes) && + visitor->Visit("supportedStencilResolveModes", + &properties->supportedStencilResolveModes) && + visitor->Visit("independentResolveNone", + &properties->independentResolveNone) && + visitor->Visit("independentResolve", &properties->independentResolve) && + visitor->Visit("filterMinmaxSingleComponentFormats", + &properties->filterMinmaxSingleComponentFormats) && + visitor->Visit("filterMinmaxImageComponentMapping", + &properties->filterMinmaxImageComponentMapping) && + visitor->Visit("maxTimelineSemaphoreValueDifference", + &properties->maxTimelineSemaphoreValueDifference) && + visitor->Visit("framebufferIntegerColorSampleCounts", + &properties->framebufferIntegerColorSampleCounts); } template <typename Visitor> inline bool Iterate(Visitor* visitor, - VkExternalSemaphoreProperties* properties) { - return visitor->Visit("exportFromImportedHandleTypes", - &properties->exportFromImportedHandleTypes) && - visitor->Visit("compatibleHandleTypes", - &properties->compatibleHandleTypes) && - visitor->Visit("externalSemaphoreFeatures", - &properties->externalSemaphoreFeatures); + VkPhysicalDeviceVulkan12Features* features) { + return + + visitor->Visit("samplerMirrorClampToEdge", + &features->samplerMirrorClampToEdge) && + visitor->Visit("drawIndirectCount", &features->drawIndirectCount) && + visitor->Visit("storageBuffer8BitAccess", + &features->storageBuffer8BitAccess) && + visitor->Visit("uniformAndStorageBuffer8BitAccess", + &features->uniformAndStorageBuffer8BitAccess) && + visitor->Visit("storagePushConstant8", &features->storagePushConstant8) && + visitor->Visit("shaderBufferInt64Atomics", + &features->shaderBufferInt64Atomics) && + visitor->Visit("shaderSharedInt64Atomics", + &features->shaderSharedInt64Atomics) && + visitor->Visit("shaderFloat16", &features->shaderFloat16) && + visitor->Visit("shaderInt8", &features->shaderInt8) && + visitor->Visit("descriptorIndexing", &features->descriptorIndexing) && + visitor->Visit("shaderInputAttachmentArrayDynamicIndexing", + &features->shaderInputAttachmentArrayDynamicIndexing) && + visitor->Visit("shaderUniformTexelBufferArrayDynamicIndexing", + &features->shaderUniformTexelBufferArrayDynamicIndexing) && + visitor->Visit("shaderStorageTexelBufferArrayDynamicIndexing", + &features->shaderStorageTexelBufferArrayDynamicIndexing) && + visitor->Visit("shaderUniformBufferArrayNonUniformIndexing", + &features->shaderUniformBufferArrayNonUniformIndexing) && + visitor->Visit("shaderSampledImageArrayNonUniformIndexing", + &features->shaderSampledImageArrayNonUniformIndexing) && + visitor->Visit("shaderStorageBufferArrayNonUniformIndexing", + &features->shaderStorageBufferArrayNonUniformIndexing) && + visitor->Visit("shaderStorageImageArrayNonUniformIndexing", + &features->shaderStorageImageArrayNonUniformIndexing) && + visitor->Visit("shaderInputAttachmentArrayNonUniformIndexing", + &features->shaderInputAttachmentArrayNonUniformIndexing) && + visitor->Visit( + "shaderUniformTexelBufferArrayNonUniformIndexing", + &features->shaderUniformTexelBufferArrayNonUniformIndexing) && + visitor->Visit( + "shaderStorageTexelBufferArrayNonUniformIndexing", + &features->shaderStorageTexelBufferArrayNonUniformIndexing) && + visitor->Visit( + "descriptorBindingUniformBufferUpdateAfterBind", + &features->descriptorBindingUniformBufferUpdateAfterBind) && + visitor->Visit("descriptorBindingSampledImageUpdateAfterBind", + &features->descriptorBindingSampledImageUpdateAfterBind) && + visitor->Visit("descriptorBindingStorageImageUpdateAfterBind", + &features->descriptorBindingStorageImageUpdateAfterBind) && + visitor->Visit( + "descriptorBindingStorageBufferUpdateAfterBind", + &features->descriptorBindingStorageBufferUpdateAfterBind) && + visitor->Visit( + "descriptorBindingUniformTexelBufferUpdateAfterBind", + &features->descriptorBindingUniformTexelBufferUpdateAfterBind) && + visitor->Visit( + "descriptorBindingStorageTexelBufferUpdateAfterBind", + &features->descriptorBindingStorageTexelBufferUpdateAfterBind) && + visitor->Visit("descriptorBindingUpdateUnusedWhilePending", + &features->descriptorBindingUpdateUnusedWhilePending) && + visitor->Visit("descriptorBindingPartiallyBound", + &features->descriptorBindingPartiallyBound) && + visitor->Visit("descriptorBindingVariableDescriptorCount", + &features->descriptorBindingVariableDescriptorCount) && + visitor->Visit("runtimeDescriptorArray", + &features->runtimeDescriptorArray) && + visitor->Visit("samplerFilterMinmax", &features->samplerFilterMinmax) && + visitor->Visit("scalarBlockLayout", &features->scalarBlockLayout) && + visitor->Visit("imagelessFramebuffer", &features->imagelessFramebuffer) && + visitor->Visit("uniformBufferStandardLayout", + &features->uniformBufferStandardLayout) && + visitor->Visit("shaderSubgroupExtendedTypes", + &features->shaderSubgroupExtendedTypes) && + visitor->Visit("separateDepthStencilLayouts", + &features->separateDepthStencilLayouts) && + visitor->Visit("hostQueryReset", &features->hostQueryReset) && + visitor->Visit("timelineSemaphore", &features->timelineSemaphore) && + visitor->Visit("bufferDeviceAddress", &features->bufferDeviceAddress) && + visitor->Visit("bufferDeviceAddressCaptureReplay", + &features->bufferDeviceAddressCaptureReplay) && + visitor->Visit("bufferDeviceAddressMultiDevice", + &features->bufferDeviceAddressMultiDevice) && + visitor->Visit("vulkanMemoryModel", &features->vulkanMemoryModel) && + visitor->Visit("vulkanMemoryModelDeviceScope", + &features->vulkanMemoryModelDeviceScope) && + visitor->Visit( + "vulkanMemoryModelAvailabilityVisibilityChains", + &features->vulkanMemoryModelAvailabilityVisibilityChains) && + visitor->Visit("shaderOutputViewportIndex", + &features->shaderOutputViewportIndex) && + visitor->Visit("shaderOutputLayer", &features->shaderOutputLayer) && + visitor->Visit("subgroupBroadcastDynamicId", + &features->subgroupBroadcastDynamicId); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkQueueFamilyProperties* properties) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceVulkan13Properties* properties) { return - visitor->Visit("queueFlags", &properties->queueFlags) && - visitor->Visit("queueCount", &properties->queueCount) && - visitor->Visit("timestampValidBits", &properties->timestampValidBits) && - visitor->Visit("minImageTransferGranularity", &properties->minImageTransferGranularity); + + visitor->Visit("minSubgroupSize", &properties->minSubgroupSize) && + visitor->Visit("maxSubgroupSize", &properties->maxSubgroupSize) && + visitor->Visit("maxComputeWorkgroupSubgroups", + &properties->maxComputeWorkgroupSubgroups) && + visitor->Visit("requiredSubgroupSizeStages", + &properties->requiredSubgroupSizeStages) && + visitor->Visit("maxInlineUniformBlockSize", + &properties->maxInlineUniformBlockSize) && + visitor->Visit("maxPerStageDescriptorInlineUniformBlocks", + &properties->maxPerStageDescriptorInlineUniformBlocks) && + visitor->Visit( + "maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks", + &properties + ->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks) && + visitor->Visit("maxDescriptorSetInlineUniformBlocks", + &properties->maxDescriptorSetInlineUniformBlocks) && + visitor->Visit( + "maxDescriptorSetUpdateAfterBindInlineUniformBlocks", + &properties->maxDescriptorSetUpdateAfterBindInlineUniformBlocks) && + visitor->Visit("maxInlineUniformTotalSize", + &properties->maxInlineUniformTotalSize) && + visitor->Visit("integerDotProduct8BitUnsignedAccelerated", + &properties->integerDotProduct8BitUnsignedAccelerated) && + visitor->Visit("integerDotProduct8BitSignedAccelerated", + &properties->integerDotProduct8BitSignedAccelerated) && + visitor->Visit( + "integerDotProduct8BitMixedSignednessAccelerated", + &properties->integerDotProduct8BitMixedSignednessAccelerated) && + visitor->Visit( + "integerDotProduct4x8BitPackedUnsignedAccelerated", + &properties->integerDotProduct4x8BitPackedUnsignedAccelerated) && + visitor->Visit( + "integerDotProduct4x8BitPackedSignedAccelerated", + &properties->integerDotProduct4x8BitPackedSignedAccelerated) && + visitor->Visit( + "integerDotProduct4x8BitPackedMixedSignednessAccelerated", + &properties + ->integerDotProduct4x8BitPackedMixedSignednessAccelerated) && + visitor->Visit("integerDotProduct16BitUnsignedAccelerated", + &properties->integerDotProduct16BitUnsignedAccelerated) && + visitor->Visit("integerDotProduct16BitSignedAccelerated", + &properties->integerDotProduct16BitSignedAccelerated) && + visitor->Visit( + "integerDotProduct16BitMixedSignednessAccelerated", + &properties->integerDotProduct16BitMixedSignednessAccelerated) && + visitor->Visit("integerDotProduct32BitUnsignedAccelerated", + &properties->integerDotProduct32BitUnsignedAccelerated) && + visitor->Visit("integerDotProduct32BitSignedAccelerated", + &properties->integerDotProduct32BitSignedAccelerated) && + visitor->Visit( + "integerDotProduct32BitMixedSignednessAccelerated", + &properties->integerDotProduct32BitMixedSignednessAccelerated) && + visitor->Visit("integerDotProduct64BitUnsignedAccelerated", + &properties->integerDotProduct64BitUnsignedAccelerated) && + visitor->Visit("integerDotProduct64BitSignedAccelerated", + &properties->integerDotProduct64BitSignedAccelerated) && + visitor->Visit( + "integerDotProduct64BitMixedSignednessAccelerated", + &properties->integerDotProduct64BitMixedSignednessAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating8BitUnsignedAccelerated", + &properties + ->integerDotProductAccumulatingSaturating8BitUnsignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating8BitSignedAccelerated", + &properties + ->integerDotProductAccumulatingSaturating8BitSignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerate" + "d", + &properties + ->integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerat" + "ed", + &properties + ->integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerate" + "d", + &properties + ->integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAc" + "celerated", + &properties + ->integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating16BitUnsignedAccelerated", + &properties + ->integerDotProductAccumulatingSaturating16BitUnsignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating16BitSignedAccelerated", + &properties + ->integerDotProductAccumulatingSaturating16BitSignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerat" + "ed", + &properties + ->integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating32BitUnsignedAccelerated", + &properties + ->integerDotProductAccumulatingSaturating32BitUnsignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating32BitSignedAccelerated", + &properties + ->integerDotProductAccumulatingSaturating32BitSignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerat" + "ed", + &properties + ->integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating64BitUnsignedAccelerated", + &properties + ->integerDotProductAccumulatingSaturating64BitUnsignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating64BitSignedAccelerated", + &properties + ->integerDotProductAccumulatingSaturating64BitSignedAccelerated) && + visitor->Visit( + "integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerat" + "ed", + &properties + ->integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated) && + visitor->Visit("storageTexelBufferOffsetAlignmentBytes", + &properties->storageTexelBufferOffsetAlignmentBytes) && + visitor->Visit( + "storageTexelBufferOffsetSingleTexelAlignment", + &properties->storageTexelBufferOffsetSingleTexelAlignment) && + visitor->Visit("uniformTexelBufferOffsetAlignmentBytes", + &properties->uniformTexelBufferOffsetAlignmentBytes) && + visitor->Visit( + "uniformTexelBufferOffsetSingleTexelAlignment", + &properties->uniformTexelBufferOffsetSingleTexelAlignment) && + visitor->Visit("maxBufferSize", &properties->maxBufferSize); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkExtensionProperties* properties) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceVulkan13Features* features) { return - visitor->Visit("extensionName", &properties->extensionName) && - visitor->Visit("specVersion", &properties->specVersion); + + visitor->Visit("robustImageAccess", &features->robustImageAccess) && + visitor->Visit("inlineUniformBlock", &features->inlineUniformBlock) && + visitor->Visit( + "descriptorBindingInlineUniformBlockUpdateAfterBind", + &features->descriptorBindingInlineUniformBlockUpdateAfterBind) && + visitor->Visit("pipelineCreationCacheControl", + &features->pipelineCreationCacheControl) && + visitor->Visit("privateData", &features->privateData) && + visitor->Visit("shaderDemoteToHelperInvocation", + &features->shaderDemoteToHelperInvocation) && + visitor->Visit("shaderTerminateInvocation", + &features->shaderTerminateInvocation) && + visitor->Visit("subgroupSizeControl", &features->subgroupSizeControl) && + visitor->Visit("computeFullSubgroups", &features->computeFullSubgroups) && + visitor->Visit("synchronization2", &features->synchronization2) && + visitor->Visit("textureCompressionASTC_HDR", + &features->textureCompressionASTC_HDR) && + visitor->Visit("shaderZeroInitializeWorkgroupMemory", + &features->shaderZeroInitializeWorkgroupMemory) && + visitor->Visit("dynamicRendering", &features->dynamicRendering) && + visitor->Visit("shaderIntegerDotProduct", + &features->shaderIntegerDotProduct) && + visitor->Visit("maintenance4", &features->maintenance4); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkLayerProperties* properties) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceVulkan14Properties* properties) { return - visitor->Visit("layerName", &properties->layerName) && - visitor->Visit("specVersion", &properties->specVersion) && - visitor->Visit("implementationVersion", &properties->implementationVersion) && - visitor->Visit("description", &properties->description); + + visitor->Visit("lineSubPixelPrecisionBits", + &properties->lineSubPixelPrecisionBits) && + visitor->Visit("maxVertexAttribDivisor", + &properties->maxVertexAttribDivisor) && + visitor->Visit("supportsNonZeroFirstInstance", + &properties->supportsNonZeroFirstInstance) && + visitor->Visit("maxPushDescriptors", &properties->maxPushDescriptors) && + visitor->Visit( + "dynamicRenderingLocalReadDepthStencilAttachments", + &properties->dynamicRenderingLocalReadDepthStencilAttachments) && + visitor->Visit( + "dynamicRenderingLocalReadMultisampledAttachments", + &properties->dynamicRenderingLocalReadMultisampledAttachments) && + visitor->Visit( + "earlyFragmentMultisampleCoverageAfterSampleCounting", + &properties->earlyFragmentMultisampleCoverageAfterSampleCounting) && + visitor->Visit( + "earlyFragmentSampleMaskTestBeforeSampleCounting", + &properties->earlyFragmentSampleMaskTestBeforeSampleCounting) && + visitor->Visit("depthStencilSwizzleOneSupport", + &properties->depthStencilSwizzleOneSupport) && + visitor->Visit("polygonModePointSize", + &properties->polygonModePointSize) && + visitor->Visit( + "nonStrictSinglePixelWideLinesUseParallelogram", + &properties->nonStrictSinglePixelWideLinesUseParallelogram) && + visitor->Visit("nonStrictWideLinesUseParallelogram", + &properties->nonStrictWideLinesUseParallelogram) && + visitor->Visit("blockTexelViewCompatibleMultipleLayers", + &properties->blockTexelViewCompatibleMultipleLayers) && + visitor->Visit("maxCombinedImageSamplerDescriptorCount", + &properties->maxCombinedImageSamplerDescriptorCount) && + visitor->Visit("fragmentShadingRateClampCombinerInputs", + &properties->fragmentShadingRateClampCombinerInputs) && + visitor->Visit("defaultRobustnessStorageBuffers", + &properties->defaultRobustnessStorageBuffers) && + visitor->Visit("defaultRobustnessUniformBuffers", + &properties->defaultRobustnessUniformBuffers) && + visitor->Visit("defaultRobustnessVertexInputs", + &properties->defaultRobustnessVertexInputs) && + visitor->Visit("defaultRobustnessImages", + &properties->defaultRobustnessImages) && + visitor->Visit("copySrcLayoutCount", &properties->copySrcLayoutCount) && + visitor->VisitArray("pCopySrcLayouts", properties->copySrcLayoutCount, + &properties->pCopySrcLayouts) && + visitor->Visit("copyDstLayoutCount", &properties->copyDstLayoutCount) && + visitor->VisitArray("pCopyDstLayouts", properties->copyDstLayoutCount, + &properties->pCopyDstLayouts) && + visitor->Visit("optimalTilingLayoutUUID", + &properties->optimalTilingLayoutUUID) && + visitor->Visit("identicalMemoryTypeRequirements", + &properties->identicalMemoryTypeRequirements); } template <typename Visitor> -inline bool Iterate(Visitor* visitor, VkFormatProperties* properties) { +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceVulkan14Features* features) { return - visitor->Visit("linearTilingFeatures", &properties->linearTilingFeatures) && - visitor->Visit("optimalTilingFeatures", &properties->optimalTilingFeatures) && - visitor->Visit("bufferFeatures", &properties->bufferFeatures); + + visitor->Visit("globalPriorityQuery", &features->globalPriorityQuery) && + visitor->Visit("shaderSubgroupRotate", &features->shaderSubgroupRotate) && + visitor->Visit("shaderSubgroupRotateClustered", + &features->shaderSubgroupRotateClustered) && + visitor->Visit("shaderFloatControls2", &features->shaderFloatControls2) && + visitor->Visit("shaderExpectAssume", &features->shaderExpectAssume) && + visitor->Visit("rectangularLines", &features->rectangularLines) && + visitor->Visit("bresenhamLines", &features->bresenhamLines) && + visitor->Visit("smoothLines", &features->smoothLines) && + visitor->Visit("stippledRectangularLines", + &features->stippledRectangularLines) && + visitor->Visit("stippledBresenhamLines", + &features->stippledBresenhamLines) && + visitor->Visit("stippledSmoothLines", &features->stippledSmoothLines) && + visitor->Visit("vertexAttributeInstanceRateDivisor", + &features->vertexAttributeInstanceRateDivisor) && + visitor->Visit("vertexAttributeInstanceRateZeroDivisor", + &features->vertexAttributeInstanceRateZeroDivisor) && + visitor->Visit("indexTypeUint8", &features->indexTypeUint8) && + visitor->Visit("dynamicRenderingLocalRead", + &features->dynamicRenderingLocalRead) && + visitor->Visit("maintenance5", &features->maintenance5) && + visitor->Visit("maintenance6", &features->maintenance6) && + visitor->Visit("pipelineProtectedAccess", + &features->pipelineProtectedAccess) && + visitor->Visit("pipelineRobustness", &features->pipelineRobustness) && + visitor->Visit("hostImageCopy", &features->hostImageCopy); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkPhysicalDeviceDriverProperties* properties) { + return + + visitor->Visit("driverID", &properties->driverID) && + visitor->Visit("driverName", &properties->driverName) && + visitor->Visit("driverInfo", &properties->driverInfo) && + visitor->Visit("conformanceVersion", &properties->conformanceVersion); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, VkExternalFenceProperties* properties) { + return visitor->Visit("exportFromImportedHandleTypes", + &properties->exportFromImportedHandleTypes) && + visitor->Visit("compatibleHandleTypes", + &properties->compatibleHandleTypes) && + visitor->Visit("externalFenceFeatures", + &properties->externalFenceFeatures); +} + +template <typename Visitor> +inline bool Iterate(Visitor* visitor, + VkExternalSemaphoreProperties* properties) { + return visitor->Visit("exportFromImportedHandleTypes", + &properties->exportFromImportedHandleTypes) && + visitor->Visit("compatibleHandleTypes", + &properties->compatibleHandleTypes) && + visitor->Visit("externalSemaphoreFeatures", + &properties->externalSemaphoreFeatures); } template <typename Visitor> @@ -1191,6 +1953,7 @@ inline bool Iterate(Visitor* visitor, VkJsonDevice* device) { ret &= visitor->Visit("core13", &device->core13); FALLTHROUGH_INTENDED; case VK_API_VERSION_1_2: + ret &= visitor->Visit("core11", &device->core11); ret &= visitor->Visit("core12", &device->core12); FALLTHROUGH_INTENDED; case VK_API_VERSION_1_1: @@ -1203,17 +1966,17 @@ inline bool Iterate(Visitor* visitor, VkJsonDevice* device) { visitor->Visit("idProperties", &device->id_properties) && visitor->Visit("maintenance3Properties", &device->maintenance3_properties) && - visitor->Visit("16bitStorageFeatures", - &device->bit16_storage_features) && visitor->Visit("multiviewFeatures", &device->multiview_features) && - visitor->Visit("variablePointerFeatures", - &device->variable_pointer_features) && + visitor->Visit("variablePointersFeatures", + &device->variable_pointers_features) && visitor->Visit("protectedMemoryFeatures", &device->protected_memory_features) && visitor->Visit("samplerYcbcrConversionFeatures", &device->sampler_ycbcr_conversion_features) && visitor->Visit("shaderDrawParameterFeatures", &device->shader_draw_parameter_features) && + visitor->Visit("bit16StorageFeatures", + &device->bit16_storage_features) && visitor->Visit("externalFenceProperties", &device->external_fence_properties) && visitor->Visit("externalSemaphoreProperties", @@ -1227,17 +1990,90 @@ inline bool Iterate(Visitor* visitor, VkJsonDevice* device) { visitor->Visit("extensions", &device->extensions) && visitor->Visit("layers", &device->layers) && visitor->Visit("formats", &device->formats); - if (device->ext_driver_properties.reported) { - ret &= visitor->Visit("VK_KHR_driver_properties", - &device->ext_driver_properties); - } - if (device->ext_variable_pointer_features.reported) { + + if (device->khr_variable_pointers.reported) { ret &= visitor->Visit("VK_KHR_variable_pointers", - &device->ext_variable_pointer_features); + &device->khr_variable_pointers); } - if (device->ext_shader_float16_int8_features.reported) { + if (device->khr_shader_float16_int8.reported) { ret &= visitor->Visit("VK_KHR_shader_float16_int8", - &device->ext_shader_float16_int8_features); + &device->khr_shader_float16_int8); + } + if (device->ext_image_2d_view_of_3d.reported) { + ret &= visitor->Visit("VK_EXT_image_2d_view_of_3d", + &device->ext_image_2d_view_of_3d); + } + if (device->ext_custom_border_color.reported) { + ret &= visitor->Visit("VK_EXT_custom_border_color", + &device->ext_custom_border_color); + } + if (device->ext_primitive_topology_list_restart.reported) { + ret &= visitor->Visit("VK_EXT_primitive_topology_list_restart", + &device->ext_primitive_topology_list_restart); + } + if (device->ext_provoking_vertex.reported) { + ret &= visitor->Visit("VK_EXT_provoking_vertex", + &device->ext_provoking_vertex); + } + if (device->khr_index_type_uint8.reported) { + ret &= visitor->Visit("VK_KHR_index_type_uint8", + &device->khr_index_type_uint8); + } + if (device->ext_index_type_uint8.reported) { + ret &= visitor->Visit("VK_EXT_index_type_uint8", + &device->ext_index_type_uint8); + } + if (device->khr_vertex_attribute_divisor.reported) { + ret &= visitor->Visit("VK_KHR_vertex_attribute_divisor", + &device->khr_vertex_attribute_divisor); + } + if (device->ext_vertex_attribute_divisor.reported) { + ret &= visitor->Visit("VK_EXT_vertex_attribute_divisor", + &device->ext_vertex_attribute_divisor); + } + if (device->ext_transform_feedback.reported) { + ret &= visitor->Visit("VK_EXT_transform_feedback", + &device->ext_transform_feedback); + } + if (device->khr_shader_subgroup_uniform_control_flow.reported) { + ret &= + visitor->Visit("VK_KHR_shader_subgroup_uniform_control_flow", + &device->khr_shader_subgroup_uniform_control_flow); + } + if (device->khr_shader_subgroup_extended_types.reported) { + ret &= visitor->Visit("VK_KHR_shader_subgroup_extended_types", + &device->khr_shader_subgroup_extended_types); + } + if (device->khr_8bit_storage.reported) { + ret &= visitor->Visit("VK_KHR_8bit_storage", &device->khr_8bit_storage); + } + if (device->khr_shader_integer_dot_product.reported) { + ret &= visitor->Visit("VK_KHR_shader_integer_dot_product", + &device->khr_shader_integer_dot_product); + } + if (device->img_relaxed_line_rasterization.reported) { + ret &= visitor->Visit("VK_IMG_relaxed_line_rasterization", + &device->img_relaxed_line_rasterization); + } + if (device->khr_line_rasterization.reported) { + ret &= visitor->Visit("VK_KHR_line_rasterization", + &device->khr_line_rasterization); + } + if (device->ext_line_rasterization.reported) { + ret &= visitor->Visit("VK_EXT_line_rasterization", + &device->ext_line_rasterization); + } + if (device->ext_primitives_generated_query.reported) { + ret &= visitor->Visit("VK_EXT_primitives_generated_query", + &device->ext_primitives_generated_query); + } + if (device->khr_shader_float_controls.reported) { + ret &= visitor->Visit("VK_KHR_shader_float_controls", + &device->khr_shader_float_controls); + } + if (device->khr_driver_properties.reported) { + ret &= visitor->Visit("VK_KHR_driver_properties", + &device->khr_driver_properties); } } return ret; @@ -1295,7 +2131,9 @@ inline Json::Value ToJsonValue(const uint64_t& value) { return Json::Value(string); } -template <typename T, typename = EnableForEnum<T>, typename = void, +template <typename T, + typename = EnableForEnum<T>, + typename = void, typename = void> inline Json::Value ToJsonValue(const T& value) { return Json::Value(static_cast<double>(value)); @@ -1304,7 +2142,8 @@ inline Json::Value ToJsonValue(const T& value) { template <typename T> inline Json::Value ArrayToJsonValue(uint32_t count, const T* values) { Json::Value array(Json::arrayValue); - for (unsigned int i = 0; i < count; ++i) array.append(ToJsonValue(values[i])); + for (unsigned int i = 0; i < count; ++i) + array.append(ToJsonValue(values[i])); return array; } @@ -1336,7 +2175,8 @@ inline Json::Value ToJsonValue(const std::pair<F, S>& value) { template <typename F, typename S> inline Json::Value ToJsonValue(const std::map<F, S>& value) { Json::Value array(Json::arrayValue); - for (auto& kv : value) array.append(ToJsonValue(kv)); + for (auto& kv : value) + array.append(ToJsonValue(kv)); return array; } @@ -1346,7 +2186,8 @@ class JsonWriterVisitor { ~JsonWriterVisitor() {} - template <typename T> bool Visit(const char* key, const T* value) { + template <typename T> + bool Visit(const char* key, const T* value) { object_[key] = ToJsonValue(*value); return true; } @@ -1359,7 +2200,7 @@ class JsonWriterVisitor { } template <typename T> - bool VisitArray(const char* key, uint32_t count, const T *value) { + bool VisitArray(const char* key, uint32_t count, const T* value) { object_[key] = ArrayToJsonValue(count, *value); return true; } @@ -1386,7 +2227,8 @@ template <typename T, typename = EnableForStruct<T>> bool AsValue(Json::Value* json_value, T* t); inline bool AsValue(Json::Value* json_value, int32_t* value) { - if (json_value->type() != Json::realValue) return false; + if (json_value->type() != Json::realValue) + return false; double d = json_value->asDouble(); if (!IsIntegral(d) || d < static_cast<double>(std::numeric_limits<int32_t>::min()) || @@ -1397,14 +2239,16 @@ inline bool AsValue(Json::Value* json_value, int32_t* value) { } inline bool AsValue(Json::Value* json_value, uint64_t* value) { - if (json_value->type() != Json::stringValue) return false; + if (json_value->type() != Json::stringValue) + return false; int result = std::sscanf(json_value->asString().c_str(), "0x%016" PRIx64, value); return result == 1; } inline bool AsValue(Json::Value* json_value, uint32_t* value) { - if (json_value->type() != Json::realValue) return false; + if (json_value->type() != Json::realValue) + return false; double d = json_value->asDouble(); if (!IsIntegral(d) || d < 0.0 || d > static_cast<double>(std::numeric_limits<uint32_t>::max())) @@ -1423,7 +2267,8 @@ inline bool AsValue(Json::Value* json_value, uint8_t* value) { } inline bool AsValue(Json::Value* json_value, float* value) { - if (json_value->type() != Json::realValue) return false; + if (json_value->type() != Json::realValue) + return false; *value = static_cast<float>(json_value->asDouble()); return true; } @@ -1432,7 +2277,8 @@ inline bool AsValue(Json::Value* json_value, VkImageLayout* t) { uint32_t value = 0; if (!AsValue(json_value, &value)) return false; - if (!EnumTraits<VkImageLayout>::exist(value)) return false; + if (!EnumTraits<VkImageLayout>::exist(value)) + return false; *t = static_cast<VkImageLayout>(value); return true; } @@ -1442,7 +2288,8 @@ inline bool AsArray(Json::Value* json_value, uint32_t count, T* values) { if (json_value->type() != Json::arrayValue || json_value->size() != count) return false; for (uint32_t i = 0; i < count; ++i) { - if (!AsValue(&(*json_value)[i], values + i)) return false; + if (!AsValue(&(*json_value)[i], values + i)) + return false; } return true; } @@ -1454,12 +2301,13 @@ inline bool AsValue(Json::Value* json_value, T (*value)[N]) { template <size_t N> inline bool AsValue(Json::Value* json_value, char (*value)[N]) { - if (json_value->type() != Json::stringValue) return false; + if (json_value->type() != Json::stringValue) + return false; size_t len = json_value->asString().length(); if (len >= N) return false; memcpy(*value, json_value->asString().c_str(), len); - memset(*value + len, 0, N-len); + memset(*value + len, 0, N - len); return true; } @@ -1467,15 +2315,17 @@ template <typename T, typename = EnableForEnum<T>, typename = void> inline bool AsValue(Json::Value* json_value, T* t) { uint32_t value = 0; if (!AsValue(json_value, &value)) - return false; - if (!EnumTraits<T>::exist(value)) return false; + return false; + if (!EnumTraits<T>::exist(value)) + return false; *t = static_cast<T>(value); return true; } template <typename T> inline bool AsValue(Json::Value* json_value, std::vector<T>* value) { - if (json_value->type() != Json::arrayValue) return false; + if (json_value->type() != Json::arrayValue) + return false; int size = json_value->size(); value->resize(size); return AsArray(json_value, size, value->data()); @@ -1491,11 +2341,13 @@ inline bool AsValue(Json::Value* json_value, std::pair<F, S>* value) { template <typename F, typename S> inline bool AsValue(Json::Value* json_value, std::map<F, S>* value) { - if (json_value->type() != Json::arrayValue) return false; + if (json_value->type() != Json::arrayValue) + return false; int size = json_value->size(); for (int i = 0; i < size; ++i) { std::pair<F, S> elem; - if (!AsValue(&(*json_value)[i], &elem)) return false; + if (!AsValue(&(*json_value)[i], &elem)) + return false; if (!value->insert(elem).second) return false; } @@ -1503,7 +2355,9 @@ inline bool AsValue(Json::Value* json_value, std::map<F, S>* value) { } template <typename T> -bool ReadValue(Json::Value* object, const char* key, T* value, +bool ReadValue(Json::Value* object, + const char* key, + T* value, std::string* errors) { Json::Value json_value = (*object)[key]; if (!json_value) { @@ -1511,7 +2365,8 @@ bool ReadValue(Json::Value* object, const char* key, T* value, *errors = std::string(key) + " missing."; return false; } - if (AsValue(&json_value, value)) return true; + if (AsValue(&json_value, value)) + return true; if (errors) *errors = std::string("Wrong type for ") + std::string(key) + "."; return false; @@ -1527,7 +2382,8 @@ class JsonReaderVisitor { JsonReaderVisitor(Json::Value* object, std::string* errors) : object_(object), errors_(errors) {} - template <typename T> bool Visit(const char* key, T* value) const { + template <typename T> + bool Visit(const char* key, T* value) const { return ReadValue(object_, key, value, errors_); } @@ -1541,27 +2397,28 @@ class JsonReaderVisitor { *errors_ = std::string(key) + " missing."; return false; } - if (AsArray(&json_value, count, *value)) return true; + if (AsArray(&json_value, count, *value)) + return true; if (errors_) *errors_ = std::string("Wrong type for ") + std::string(key) + "."; return false; } template <typename T> - bool VisitArray(const char* key, uint32_t count, T *value) { + bool VisitArray(const char* key, uint32_t count, T* value) { Json::Value json_value = (*object_)[key]; if (!json_value) { if (errors_) *errors_ = std::string(key) + " missing."; return false; } - if (AsArray(&json_value, count, *value)) return true; + if (AsArray(&json_value, count, *value)) + return true; if (errors_) *errors_ = std::string("Wrong type for ") + std::string(key) + "."; return false; } - private: Json::Value* object_; std::string* errors_; @@ -1569,21 +2426,21 @@ class JsonReaderVisitor { template <typename T, typename /*= EnableForStruct<T>*/> bool AsValue(Json::Value* json_value, T* t) { - if (json_value->type() != Json::objectValue) return false; + if (json_value->type() != Json::objectValue) + return false; JsonReaderVisitor visitor(json_value, nullptr); return VisitForRead(&visitor, t); } - -template <typename T> std::string VkTypeToJson(const T& t) { +template <typename T> +std::string VkTypeToJson(const T& t) { JsonWriterVisitor visitor; VisitForWrite(&visitor, t); return visitor.get_object().toStyledString(); } -template <typename T> bool VkTypeFromJson(const std::string& json, - T* t, - std::string* errors) { +template <typename T> +bool VkTypeFromJson(const std::string& json, T* t, std::string* errors) { *t = T(); Json::Value object(Json::objectValue); Json::CharReaderBuilder builder; diff --git a/vulkan/vkjson/vkjson.h b/vulkan/vkjson/vkjson.h index 28de680a99..d74644ca8e 100644 --- a/vulkan/vkjson/vkjson.h +++ b/vulkan/vkjson/vkjson.h @@ -21,8 +21,8 @@ #ifndef VKJSON_H_ #define VKJSON_H_ -#include <vulkan/vulkan.h> #include <string.h> +#include <vulkan/vulkan.h> #include <map> #include <string> @@ -33,45 +33,238 @@ #undef max #endif -/* - * Annotation to tell clang that we intend to fall through from one case to - * another in a switch. Sourced from android-base/macros.h. - */ -#define FALLTHROUGH_INTENDED [[clang::fallthrough]] - struct VkJsonLayer { VkLayerProperties properties; std::vector<VkExtensionProperties> extensions; }; -struct VkJsonExtDriverProperties { - VkJsonExtDriverProperties() { - reported = false; - memset(&driver_properties_khr, 0, - sizeof(VkPhysicalDeviceDriverPropertiesKHR)); - } - bool reported; - VkPhysicalDeviceDriverPropertiesKHR driver_properties_khr; -}; - -struct VkJsonExtVariablePointerFeatures { - VkJsonExtVariablePointerFeatures() { +struct VkJsonKHRVariablePointers { + VkJsonKHRVariablePointers() { reported = false; memset(&variable_pointer_features_khr, 0, sizeof(VkPhysicalDeviceVariablePointerFeaturesKHR)); + memset(&variable_pointers_features_khr, 0, + sizeof(VkPhysicalDeviceVariablePointersFeaturesKHR)); } bool reported; VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointer_features_khr; + VkPhysicalDeviceVariablePointersFeaturesKHR variable_pointers_features_khr; }; -struct VkJsonExtShaderFloat16Int8Features { - VkJsonExtShaderFloat16Int8Features() { +struct VkJsonKHRShaderFloat16Int8 { + VkJsonKHRShaderFloat16Int8() { reported = false; memset(&shader_float16_int8_features_khr, 0, sizeof(VkPhysicalDeviceShaderFloat16Int8FeaturesKHR)); + memset(&float16_int8_features_khr, 0, + sizeof(VkPhysicalDeviceFloat16Int8FeaturesKHR)); } bool reported; VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_float16_int8_features_khr; + VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8_features_khr; +}; + +struct VkJsonExtImage2dViewOf3d { + VkJsonExtImage2dViewOf3d() { + reported = false; + memset(&image_2d_view_of_3d_features_ext, 0, + sizeof(VkPhysicalDeviceImage2DViewOf3DFeaturesEXT)); + } + bool reported; + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT image_2d_view_of_3d_features_ext; +}; + +struct VkJsonExtCustomBorderColor { + VkJsonExtCustomBorderColor() { + reported = false; + memset(&custom_border_color_features_ext, 0, + sizeof(VkPhysicalDeviceCustomBorderColorFeaturesEXT)); + } + bool reported; + VkPhysicalDeviceCustomBorderColorFeaturesEXT custom_border_color_features_ext; +}; + +struct VkJsonExtPrimitiveTopologyListRestart { + VkJsonExtPrimitiveTopologyListRestart() { + reported = false; + memset(&primitive_topology_list_restart_features_ext, 0, + sizeof(VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT)); + } + bool reported; + VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT + primitive_topology_list_restart_features_ext; +}; + +struct VkJsonExtProvokingVertex { + VkJsonExtProvokingVertex() { + reported = false; + memset(&provoking_vertex_features_ext, 0, + sizeof(VkPhysicalDeviceProvokingVertexFeaturesEXT)); + } + bool reported; + VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_features_ext; +}; + +struct VkJsonKHRIndexTypeUint8 { + VkJsonKHRIndexTypeUint8() { + reported = false; + memset(&index_type_uint8_features_khr, 0, + sizeof(VkPhysicalDeviceIndexTypeUint8FeaturesKHR)); + } + bool reported; + VkPhysicalDeviceIndexTypeUint8FeaturesKHR index_type_uint8_features_khr; +}; + +struct VkJsonExtIndexTypeUint8 { + VkJsonExtIndexTypeUint8() { + reported = false; + memset(&index_type_uint8_features_ext, 0, + sizeof(VkPhysicalDeviceIndexTypeUint8FeaturesEXT)); + } + bool reported; + VkPhysicalDeviceIndexTypeUint8FeaturesEXT index_type_uint8_features_ext; +}; + +struct VkJsonKHRVertexAttributeDivisor { + VkJsonKHRVertexAttributeDivisor() { + reported = false; + memset(&vertex_attribute_divisor_features_khr, 0, + sizeof(VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR)); + } + bool reported; + VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR + vertex_attribute_divisor_features_khr; +}; + +struct VkJsonExtVertexAttributeDivisor { + VkJsonExtVertexAttributeDivisor() { + reported = false; + memset(&vertex_attribute_divisor_features_ext, 0, + sizeof(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT)); + } + bool reported; + VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT + vertex_attribute_divisor_features_ext; +}; + +struct VkJsonExtTransformFeedback { + VkJsonExtTransformFeedback() { + reported = false; + memset(&transform_feedback_features_ext, 0, + sizeof(VkPhysicalDeviceTransformFeedbackFeaturesEXT)); + } + bool reported; + VkPhysicalDeviceTransformFeedbackFeaturesEXT transform_feedback_features_ext; +}; + +struct VkJsonKHRShaderSubgroupUniformControlFlow { + VkJsonKHRShaderSubgroupUniformControlFlow() { + reported = false; + memset(&shader_subgroup_uniform_control_flow_features_khr, 0, + sizeof(VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR)); + } + bool reported; + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR + shader_subgroup_uniform_control_flow_features_khr; +}; + +struct VkJsonKHRShaderSubgroupExtendedTypes { + VkJsonKHRShaderSubgroupExtendedTypes() { + reported = false; + memset(&shader_subgroup_extended_types_features_khr, 0, + sizeof(VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR)); + } + bool reported; + VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR + shader_subgroup_extended_types_features_khr; +}; + +struct VkJsonKHR8bitStorage { + VkJsonKHR8bitStorage() { + reported = false; + memset(&bit8_storage_features_khr, 0, + sizeof(VkPhysicalDevice8BitStorageFeaturesKHR)); + } + bool reported; + VkPhysicalDevice8BitStorageFeaturesKHR bit8_storage_features_khr; +}; + +struct VkJsonKHRShaderIntegerDotProduct { + VkJsonKHRShaderIntegerDotProduct() { + reported = false; + memset(&shader_integer_dot_product_features_khr, 0, + sizeof(VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR)); + } + bool reported; + VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR + shader_integer_dot_product_features_khr; +}; + +struct VkJsonIMGRelaxedLineRasterization { + VkJsonIMGRelaxedLineRasterization() { + reported = false; + memset(&relaxed_line_rasterization_features_img, 0, + sizeof(VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG)); + } + bool reported; + VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG + relaxed_line_rasterization_features_img; +}; + +struct VkJsonKHRLineRasterization { + VkJsonKHRLineRasterization() { + reported = false; + memset(&line_rasterization_features_khr, 0, + sizeof(VkPhysicalDeviceLineRasterizationFeaturesKHR)); + } + bool reported; + VkPhysicalDeviceLineRasterizationFeaturesKHR line_rasterization_features_khr; +}; + +struct VkJsonExtLineRasterization { + VkJsonExtLineRasterization() { + reported = false; + memset(&line_rasterization_features_ext, 0, + sizeof(VkPhysicalDeviceLineRasterizationFeaturesEXT)); + } + bool reported; + VkPhysicalDeviceLineRasterizationFeaturesEXT line_rasterization_features_ext; +}; + +struct VkJsonExtPrimitivesGeneratedQuery { + VkJsonExtPrimitivesGeneratedQuery() { + reported = false; + memset(&primitives_generated_query_features_ext, 0, + sizeof(VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT)); + } + bool reported; + VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT + primitives_generated_query_features_ext; +}; + +struct VkJsonKHRShaderFloatControls { + VkJsonKHRShaderFloatControls() { + reported = false; + memset(&float_controls_properties_khr, 0, + sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)); + } + bool reported; + VkPhysicalDeviceFloatControlsPropertiesKHR float_controls_properties_khr; +}; + +struct VkJsonKHRDriverProperties { + VkJsonKHRDriverProperties() { + reported = false; + memset(&driver_properties_khr, 0, + sizeof(VkPhysicalDeviceDriverPropertiesKHR)); + } + bool reported; + VkPhysicalDeviceDriverPropertiesKHR driver_properties_khr; +}; + +struct VkJsonCore11 { + VkPhysicalDeviceVulkan11Properties properties; + VkPhysicalDeviceVulkan11Features features; }; struct VkJsonCore12 { @@ -105,28 +298,48 @@ struct VkJsonDevice { memset(&bit16_storage_features, 0, sizeof(VkPhysicalDevice16BitStorageFeatures)); memset(&multiview_features, 0, sizeof(VkPhysicalDeviceMultiviewFeatures)); - memset(&variable_pointer_features, 0, - sizeof(VkPhysicalDeviceVariablePointerFeatures)); + memset(&variable_pointers_features, 0, + sizeof(VkPhysicalDeviceVariablePointersFeatures)); memset(&protected_memory_features, 0, sizeof(VkPhysicalDeviceProtectedMemoryFeatures)); memset(&sampler_ycbcr_conversion_features, 0, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures)); memset(&shader_draw_parameter_features, 0, sizeof(VkPhysicalDeviceShaderDrawParameterFeatures)); + memset(&core11, 0, sizeof(VkJsonCore11)); memset(&core12, 0, sizeof(VkJsonCore12)); memset(&core13, 0, sizeof(VkJsonCore13)); memset(&core14, 0, sizeof(VkJsonCore14)); } + VkJsonKHRVariablePointers khr_variable_pointers; + VkJsonKHRShaderFloat16Int8 khr_shader_float16_int8; + VkJsonExtImage2dViewOf3d ext_image_2d_view_of_3d; + VkJsonExtCustomBorderColor ext_custom_border_color; + VkJsonExtPrimitiveTopologyListRestart ext_primitive_topology_list_restart; + VkJsonExtProvokingVertex ext_provoking_vertex; + VkJsonKHRIndexTypeUint8 khr_index_type_uint8; + VkJsonExtIndexTypeUint8 ext_index_type_uint8; + VkJsonKHRVertexAttributeDivisor khr_vertex_attribute_divisor; + VkJsonExtVertexAttributeDivisor ext_vertex_attribute_divisor; + VkJsonExtTransformFeedback ext_transform_feedback; + VkJsonKHRShaderSubgroupUniformControlFlow + khr_shader_subgroup_uniform_control_flow; + VkJsonKHRShaderSubgroupExtendedTypes khr_shader_subgroup_extended_types; + VkJsonKHR8bitStorage khr_8bit_storage; + VkJsonKHRShaderIntegerDotProduct khr_shader_integer_dot_product; + VkJsonIMGRelaxedLineRasterization img_relaxed_line_rasterization; + VkJsonKHRLineRasterization khr_line_rasterization; + VkJsonExtLineRasterization ext_line_rasterization; + VkJsonExtPrimitivesGeneratedQuery ext_primitives_generated_query; + VkJsonKHRShaderFloatControls khr_shader_float_controls; + VkJsonKHRDriverProperties khr_driver_properties; + VkJsonCore11 core11; + VkJsonCore12 core12; + VkJsonCore13 core13; + VkJsonCore14 core14; VkPhysicalDeviceProperties properties; VkPhysicalDeviceFeatures features; - VkJsonExtDriverProperties ext_driver_properties; - VkJsonExtVariablePointerFeatures ext_variable_pointer_features; - VkJsonExtShaderFloat16Int8Features ext_shader_float16_int8_features; VkPhysicalDeviceMemoryProperties memory; - std::vector<VkQueueFamilyProperties> queues; - std::vector<VkExtensionProperties> extensions; - std::vector<VkLayerProperties> layers; - std::map<VkFormat, VkFormatProperties> formats; VkPhysicalDeviceSubgroupProperties subgroup_properties; VkPhysicalDevicePointClippingProperties point_clipping_properties; VkPhysicalDeviceMultiviewProperties multiview_properties; @@ -134,18 +347,19 @@ struct VkJsonDevice { VkPhysicalDeviceMaintenance3Properties maintenance3_properties; VkPhysicalDevice16BitStorageFeatures bit16_storage_features; VkPhysicalDeviceMultiviewFeatures multiview_features; - VkPhysicalDeviceVariablePointerFeatures variable_pointer_features; + VkPhysicalDeviceVariablePointersFeatures variable_pointers_features; VkPhysicalDeviceProtectedMemoryFeatures protected_memory_features; VkPhysicalDeviceSamplerYcbcrConversionFeatures sampler_ycbcr_conversion_features; VkPhysicalDeviceShaderDrawParameterFeatures shader_draw_parameter_features; + std::vector<VkQueueFamilyProperties> queues; + std::vector<VkExtensionProperties> extensions; + std::vector<VkLayerProperties> layers; + std::map<VkFormat, VkFormatProperties> formats; std::map<VkExternalFenceHandleTypeFlagBits, VkExternalFenceProperties> external_fence_properties; std::map<VkExternalSemaphoreHandleTypeFlagBits, VkExternalSemaphoreProperties> external_semaphore_properties; - VkJsonCore12 core12; - VkJsonCore13 core13; - VkJsonCore14 core14; }; struct VkJsonDeviceGroup { @@ -199,4 +413,4 @@ inline bool VkJsonAllPropertiesFromJson(const std::string& json, return VkJsonDeviceFromJson(json, properties, errors); } -#endif // VKJSON_H_ +#endif // VKJSON_H_
\ No newline at end of file diff --git a/vulkan/vkjson/vkjson_instance.cc b/vulkan/vkjson/vkjson_instance.cc index 32bc50b5f8..22b3204e61 100644 --- a/vulkan/vkjson/vkjson_instance.cc +++ b/vulkan/vkjson/vkjson_instance.cc @@ -79,13 +79,25 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) { nullptr, {}, }; + + if (HasExtension("VK_KHR_shader_float_controls", device.extensions)) { + device.khr_shader_float_controls.reported = true; + device.khr_shader_float_controls.float_controls_properties_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES; + device.khr_shader_float_controls.float_controls_properties_khr.pNext = + properties.pNext; + properties.pNext = + &device.khr_shader_float_controls.float_controls_properties_khr; + } + if (HasExtension("VK_KHR_driver_properties", device.extensions)) { - device.ext_driver_properties.reported = true; - device.ext_driver_properties.driver_properties_khr.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR; - device.ext_driver_properties.driver_properties_khr.pNext = properties.pNext; - properties.pNext = &device.ext_driver_properties.driver_properties_khr; + device.khr_driver_properties.reported = true; + device.khr_driver_properties.driver_properties_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; + device.khr_driver_properties.driver_properties_khr.pNext = properties.pNext; + properties.pNext = &device.khr_driver_properties.driver_properties_khr; } + vkGetPhysicalDeviceProperties2(physical_device, &properties); device.properties = properties.properties; @@ -94,25 +106,215 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) { nullptr, {}, }; + if (HasExtension("VK_KHR_variable_pointers", device.extensions)) { - device.ext_variable_pointer_features.reported = true; - device.ext_variable_pointer_features.variable_pointer_features_khr.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR; - device.ext_variable_pointer_features.variable_pointer_features_khr.pNext = + device.khr_variable_pointers.reported = true; + device.khr_variable_pointers.variable_pointer_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES; + device.khr_variable_pointers.variable_pointer_features_khr.pNext = features.pNext; features.pNext = - &device.ext_variable_pointer_features.variable_pointer_features_khr; + &device.khr_variable_pointers.variable_pointer_features_khr; + device.khr_variable_pointers.variable_pointers_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES; + device.khr_variable_pointers.variable_pointers_features_khr.pNext = + features.pNext; + features.pNext = + &device.khr_variable_pointers.variable_pointers_features_khr; } + if (HasExtension("VK_KHR_shader_float16_int8", device.extensions)) { - device.ext_shader_float16_int8_features.reported = true; - device.ext_shader_float16_int8_features.shader_float16_int8_features_khr + device.khr_shader_float16_int8.reported = true; + device.khr_shader_float16_int8.shader_float16_int8_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES; + device.khr_shader_float16_int8.shader_float16_int8_features_khr.pNext = + features.pNext; + features.pNext = + &device.khr_shader_float16_int8.shader_float16_int8_features_khr; + device.khr_shader_float16_int8.float16_int8_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES; + device.khr_shader_float16_int8.float16_int8_features_khr.pNext = + features.pNext; + features.pNext = &device.khr_shader_float16_int8.float16_int8_features_khr; + } + + if (HasExtension("VK_EXT_image_2d_view_of_3d", device.extensions)) { + device.ext_image_2d_view_of_3d.reported = true; + device.ext_image_2d_view_of_3d.image_2d_view_of_3d_features_ext.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT; + device.ext_image_2d_view_of_3d.image_2d_view_of_3d_features_ext.pNext = + features.pNext; + features.pNext = + &device.ext_image_2d_view_of_3d.image_2d_view_of_3d_features_ext; + } + + if (HasExtension("VK_EXT_custom_border_color", device.extensions)) { + device.ext_custom_border_color.reported = true; + device.ext_custom_border_color.custom_border_color_features_ext.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT; + device.ext_custom_border_color.custom_border_color_features_ext.pNext = + features.pNext; + features.pNext = + &device.ext_custom_border_color.custom_border_color_features_ext; + } + + if (HasExtension("VK_EXT_primitive_topology_list_restart", + device.extensions)) { + device.ext_primitive_topology_list_restart.reported = true; + device.ext_primitive_topology_list_restart + .primitive_topology_list_restart_features_ext.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT; + device.ext_primitive_topology_list_restart + .primitive_topology_list_restart_features_ext.pNext = features.pNext; + features.pNext = &device.ext_primitive_topology_list_restart + .primitive_topology_list_restart_features_ext; + } + + if (HasExtension("VK_EXT_provoking_vertex", device.extensions)) { + device.ext_provoking_vertex.reported = true; + device.ext_provoking_vertex.provoking_vertex_features_ext.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT; + device.ext_provoking_vertex.provoking_vertex_features_ext.pNext = + features.pNext; + features.pNext = &device.ext_provoking_vertex.provoking_vertex_features_ext; + } + + if (HasExtension("VK_KHR_index_type_uint8", device.extensions)) { + device.khr_index_type_uint8.reported = true; + device.khr_index_type_uint8.index_type_uint8_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES; + device.khr_index_type_uint8.index_type_uint8_features_khr.pNext = + features.pNext; + features.pNext = &device.khr_index_type_uint8.index_type_uint8_features_khr; + } + + if (HasExtension("VK_EXT_index_type_uint8", device.extensions)) { + device.ext_index_type_uint8.reported = true; + device.ext_index_type_uint8.index_type_uint8_features_ext.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES; + device.ext_index_type_uint8.index_type_uint8_features_ext.pNext = + features.pNext; + features.pNext = &device.ext_index_type_uint8.index_type_uint8_features_ext; + } + + if (HasExtension("VK_KHR_vertex_attribute_divisor", device.extensions)) { + device.khr_vertex_attribute_divisor.reported = true; + device.khr_vertex_attribute_divisor.vertex_attribute_divisor_features_khr .sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR; - device.ext_shader_float16_int8_features.shader_float16_int8_features_khr + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES; + device.khr_vertex_attribute_divisor.vertex_attribute_divisor_features_khr .pNext = features.pNext; - features.pNext = &device.ext_shader_float16_int8_features - .shader_float16_int8_features_khr; + features.pNext = &device.khr_vertex_attribute_divisor + .vertex_attribute_divisor_features_khr; } + + if (HasExtension("VK_EXT_vertex_attribute_divisor", device.extensions)) { + device.ext_vertex_attribute_divisor.reported = true; + device.ext_vertex_attribute_divisor.vertex_attribute_divisor_features_ext + .sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES; + device.ext_vertex_attribute_divisor.vertex_attribute_divisor_features_ext + .pNext = features.pNext; + features.pNext = &device.ext_vertex_attribute_divisor + .vertex_attribute_divisor_features_ext; + } + + if (HasExtension("VK_EXT_transform_feedback", device.extensions)) { + device.ext_transform_feedback.reported = true; + device.ext_transform_feedback.transform_feedback_features_ext.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; + device.ext_transform_feedback.transform_feedback_features_ext.pNext = + features.pNext; + features.pNext = + &device.ext_transform_feedback.transform_feedback_features_ext; + } + + if (HasExtension("VK_KHR_shader_subgroup_uniform_control_flow", + device.extensions)) { + device.khr_shader_subgroup_uniform_control_flow.reported = true; + device.khr_shader_subgroup_uniform_control_flow + .shader_subgroup_uniform_control_flow_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR; + device.khr_shader_subgroup_uniform_control_flow + .shader_subgroup_uniform_control_flow_features_khr.pNext = + features.pNext; + features.pNext = &device.khr_shader_subgroup_uniform_control_flow + .shader_subgroup_uniform_control_flow_features_khr; + } + + if (HasExtension("VK_KHR_shader_subgroup_extended_types", + device.extensions)) { + device.khr_shader_subgroup_extended_types.reported = true; + device.khr_shader_subgroup_extended_types + .shader_subgroup_extended_types_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES; + device.khr_shader_subgroup_extended_types + .shader_subgroup_extended_types_features_khr.pNext = features.pNext; + features.pNext = &device.khr_shader_subgroup_extended_types + .shader_subgroup_extended_types_features_khr; + } + + if (HasExtension("VK_KHR_8bit_storage", device.extensions)) { + device.khr_8bit_storage.reported = true; + device.khr_8bit_storage.bit8_storage_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES; + device.khr_8bit_storage.bit8_storage_features_khr.pNext = features.pNext; + features.pNext = &device.khr_8bit_storage.bit8_storage_features_khr; + } + + if (HasExtension("VK_KHR_shader_integer_dot_product", device.extensions)) { + device.khr_shader_integer_dot_product.reported = true; + device.khr_shader_integer_dot_product + .shader_integer_dot_product_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES; + device.khr_shader_integer_dot_product + .shader_integer_dot_product_features_khr.pNext = features.pNext; + features.pNext = &device.khr_shader_integer_dot_product + .shader_integer_dot_product_features_khr; + } + + if (HasExtension("VK_IMG_relaxed_line_rasterization", device.extensions)) { + device.img_relaxed_line_rasterization.reported = true; + device.img_relaxed_line_rasterization + .relaxed_line_rasterization_features_img.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG; + device.img_relaxed_line_rasterization + .relaxed_line_rasterization_features_img.pNext = features.pNext; + features.pNext = &device.img_relaxed_line_rasterization + .relaxed_line_rasterization_features_img; + } + + if (HasExtension("VK_KHR_line_rasterization", device.extensions)) { + device.khr_line_rasterization.reported = true; + device.khr_line_rasterization.line_rasterization_features_khr.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES; + device.khr_line_rasterization.line_rasterization_features_khr.pNext = + features.pNext; + features.pNext = + &device.khr_line_rasterization.line_rasterization_features_khr; + } + + if (HasExtension("VK_EXT_line_rasterization", device.extensions)) { + device.ext_line_rasterization.reported = true; + device.ext_line_rasterization.line_rasterization_features_ext.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES; + device.ext_line_rasterization.line_rasterization_features_ext.pNext = + features.pNext; + features.pNext = + &device.ext_line_rasterization.line_rasterization_features_ext; + } + + if (HasExtension("VK_EXT_primitives_generated_query", device.extensions)) { + device.ext_primitives_generated_query.reported = true; + device.ext_primitives_generated_query + .primitives_generated_query_features_ext.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT; + device.ext_primitives_generated_query + .primitives_generated_query_features_ext.pNext = features.pNext; + features.pNext = &device.ext_primitives_generated_query + .primitives_generated_query_features_ext; + } + vkGetPhysicalDeviceFeatures2(physical_device, &features); device.features = features.features; @@ -184,20 +386,15 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) { vkGetPhysicalDeviceProperties2(physical_device, &properties); - device.bit16_storage_features.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES; - device.bit16_storage_features.pNext = features.pNext; - features.pNext = &device.bit16_storage_features; - device.multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES; device.multiview_features.pNext = features.pNext; features.pNext = &device.multiview_features; - device.variable_pointer_features.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES; - device.variable_pointer_features.pNext = features.pNext; - features.pNext = &device.variable_pointer_features; + device.variable_pointers_features.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES; + device.variable_pointers_features.pNext = features.pNext; + features.pNext = &device.variable_pointers_features; device.protected_memory_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES; @@ -210,10 +407,15 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) { features.pNext = &device.sampler_ycbcr_conversion_features; device.shader_draw_parameter_features.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES; + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES; device.shader_draw_parameter_features.pNext = features.pNext; features.pNext = &device.shader_draw_parameter_features; + device.bit16_storage_features.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES; + device.bit16_storage_features.pNext = features.pNext; + features.pNext = &device.bit16_storage_features; + vkGetPhysicalDeviceFeatures2(physical_device, &features); VkPhysicalDeviceExternalFenceInfo external_fence_info = { @@ -261,6 +463,11 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) { } if (device.properties.apiVersion >= VK_API_VERSION_1_2) { + device.core11.properties.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES; + device.core11.properties.pNext = properties.pNext; + properties.pNext = &device.core11.properties; + device.core12.properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES; device.core12.properties.pNext = properties.pNext; @@ -268,6 +475,11 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) { vkGetPhysicalDeviceProperties2(physical_device, &properties); + device.core11.features.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; + device.core11.features.pNext = features.pNext; + features.pNext = &device.core11.features; + device.core12.features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; device.core12.features.pNext = features.pNext; @@ -327,7 +539,8 @@ VkJsonInstance VkJsonGetInstance() { return VkJsonInstance(); instance.layers.reserve(count); for (auto& layer : layers) { - instance.layers.push_back(VkJsonLayer{layer, std::vector<VkExtensionProperties>()}); + instance.layers.push_back( + VkJsonLayer{layer, std::vector<VkExtensionProperties>()}); if (!EnumerateExtensions(layer.layerName, &instance.layers.back().extensions)) return VkJsonInstance(); diff --git a/vulkan/vkprofiles/generated/vulkan_profiles.cpp b/vulkan/vkprofiles/generated/vulkan_profiles.cpp index ce08b4e072..d6ed1c7ede 100644 --- a/vulkan/vkprofiles/generated/vulkan_profiles.cpp +++ b/vulkan/vkprofiles/generated/vulkan_profiles.cpp @@ -150,7 +150,7 @@ VPAPI_ATTR void GatherStructureTypes(std::vector<VkStructureType>& structureType VPAPI_ATTR bool isMultiple(double source, double multiple) { double mod = std::fmod(source, multiple); - return std::abs(mod) < 0.0001; + return std::abs(mod) < 0.0001; } VPAPI_ATTR bool isPowerOfTwo(double source) { @@ -163,8 +163,10 @@ VPAPI_ATTR bool isPowerOfTwo(double source) { using PFN_vpStructFiller = void(*)(VkBaseOutStructure* p); using PFN_vpStructComparator = bool(*)(VkBaseOutStructure* p); -using PFN_vpStructChainerCb = void(*)(VkBaseOutStructure* p, void* pUser); +using PFN_vpStructChainerCb = void(*)(VkBaseOutStructure* p, void* pUser); using PFN_vpStructChainer = void(*)(VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb); +using PFN_vpStructArrayChainerCb = void(*)(uint32_t count, VkBaseOutStructure* p, void* pUser); +using PFN_vpStructArrayChainer = void(*)(uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb); struct VpFeatureDesc { PFN_vpStructFiller pfnFiller; @@ -190,10 +192,50 @@ struct VpFormatDesc { struct VpStructChainerDesc { PFN_vpStructChainer pfnFeature; PFN_vpStructChainer pfnProperty; - PFN_vpStructChainer pfnQueueFamily; + PFN_vpStructArrayChainer pfnQueueFamily; PFN_vpStructChainer pfnFormat; }; +struct VpVideoProfileInfoDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpVideoCapabilityDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpVideoFormatDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpVideoProfileStructChainerDesc { + PFN_vpStructChainer pfnInfo; + PFN_vpStructChainer pfnCapability; + PFN_vpStructArrayChainer pfnFormat; +}; + +struct VpVideoProfileDesc { + VpVideoProfileProperties properties; + + uint32_t infoStructTypeCount; + const VkStructureType* pInfoStructTypes; + VpVideoProfileInfoDesc info; + + uint32_t capabilityStructTypeCount; + const VkStructureType* pCapabilityStructTypes; + VpVideoCapabilityDesc capability; + + uint32_t formatStructTypeCount; + const VkStructureType* pFormatStructTypes; + uint32_t formatCount; + const VpVideoFormatDesc* pFormats; + + VpVideoProfileStructChainerDesc chainers; +}; + struct VpVariantDesc { char blockName[VP_MAX_PROFILE_NAME_SIZE]; @@ -222,6 +264,9 @@ struct VpVariantDesc { const VpFormatDesc* pFormats; VpStructChainerDesc chainers; + + uint32_t videoProfileCount; + const VpVideoProfileDesc* pVideoProfiles; }; struct VpCapabilitiesDesc { @@ -234,7 +279,7 @@ struct VpProfileDesc { uint32_t minApiVersion; const detail::VpVariantDesc* pMergedCapabilities; - + uint32_t requiredProfileCount; const VpProfileProperties* pRequiredProfiles; @@ -249,6 +294,139 @@ template <typename T> VPAPI_ATTR bool vpCheckFlags(const T& actual, const uint64_t expected) { return (actual & expected) == expected; } + + +#ifdef VK_KHR_video_queue +VPAPI_ATTR void vpForEachMatchingVideoProfiles( + VkVideoProfileInfoKHR* pVideoProfileInfo, + void* pUser, + PFN_vpStructChainerCb pfnCb) { + const VkVideoChromaSubsamplingFlagsKHR chroma_subsampling_list[] = { + VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR, + VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR, + VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR, + VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR + }; + const VkVideoComponentBitDepthFlagsKHR bit_depth_list[] = { + VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, + VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR, + VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR + }; + for (size_t chromaSubsampling_idx = 0; chromaSubsampling_idx < std::size(chroma_subsampling_list); ++chromaSubsampling_idx) { + pVideoProfileInfo->chromaSubsampling = chroma_subsampling_list[chromaSubsampling_idx]; + for (size_t lumaBitDepth_idx = 0; lumaBitDepth_idx < std::size(bit_depth_list); ++lumaBitDepth_idx) { + pVideoProfileInfo->lumaBitDepth = bit_depth_list[lumaBitDepth_idx]; + for (size_t chromaBitDepth_idx = 0; chromaBitDepth_idx < std::size(bit_depth_list); ++chromaBitDepth_idx) { + pVideoProfileInfo->chromaBitDepth = bit_depth_list[chromaBitDepth_idx]; + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR; + VkVideoDecodeH264ProfileInfoKHR var_VideoDecodeH264ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR }; + var_VideoDecodeH264ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeH264ProfileInfoKHR; + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + var_VideoDecodeH264ProfileInfoKHR.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + var_VideoDecodeH264ProfileInfoKHR.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + var_VideoDecodeH264ProfileInfoKHR.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_KHR; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR; + VkVideoDecodeH265ProfileInfoKHR var_VideoDecodeH265ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR }; + var_VideoDecodeH265ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeH265ProfileInfoKHR; + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_10; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR; + VkVideoDecodeAV1ProfileInfoKHR var_VideoDecodeAV1ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR }; + var_VideoDecodeAV1ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeAV1ProfileInfoKHR; + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN; + var_VideoDecodeAV1ProfileInfoKHR.filmGrainSupport = VK_TRUE; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_HIGH; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_PROFESSIONAL; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN; + var_VideoDecodeAV1ProfileInfoKHR.filmGrainSupport = VK_FALSE; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_HIGH; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_PROFESSIONAL; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR; + VkVideoEncodeH264ProfileInfoKHR var_VideoEncodeH264ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR }; + var_VideoEncodeH264ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoEncodeH264ProfileInfoKHR; + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR; + VkVideoEncodeH265ProfileInfoKHR var_VideoEncodeH265ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR }; + var_VideoEncodeH265ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoEncodeH265ProfileInfoKHR; + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_10; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS; + pfnCb(reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo), pUser); + } + } + } + } +} +#endif // VK_KHR_video_queue #ifdef VP_ANDROID_15_minimums namespace VP_ANDROID_15_MINIMUMS { @@ -280,7 +458,9 @@ static const VkStructureType formatStructTypes[] = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, }; +namespace blocks { namespace MUST { + static const VkExtensionProperties instanceExtensions[] = { VkExtensionProperties{ VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, 1 }, VkExtensionProperties{ VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME, 1 }, @@ -305,7 +485,7 @@ static const VkExtensionProperties deviceExtensions[] = { }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); @@ -365,63 +545,63 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { - VkPhysicalDeviceFeatures2KHR* prettify_VkPhysicalDeviceFeatures2KHR = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.drawIndirectFirstInstance == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.drawIndirectFirstInstance == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.drawIndirectFirstInstance == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.samplerAnisotropy == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.samplerAnisotropy == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.samplerAnisotropy == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderImageGatherExtended == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderImageGatherExtended == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderImageGatherExtended == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageExtendedFormats == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageExtendedFormats == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageImageExtendedFormats == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageReadWithoutFormat == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageReadWithoutFormat == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageImageReadWithoutFormat == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageWriteWithoutFormat == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageWriteWithoutFormat == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageImageWriteWithoutFormat == VK_TRUE"); + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + ret = ret && (s->features.drawIndirectFirstInstance == VK_TRUE); + ret = ret && (s->features.samplerAnisotropy == VK_TRUE); + ret = ret && (s->features.shaderImageGatherExtended == VK_TRUE); + ret = ret && (s->features.shaderStorageImageExtendedFormats == VK_TRUE); + ret = ret && (s->features.shaderStorageImageReadWithoutFormat == VK_TRUE); + ret = ret && (s->features.shaderStorageImageWriteWithoutFormat == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { - VkPhysicalDeviceVulkan12Features* prettify_VkPhysicalDeviceVulkan12Features = static_cast<VkPhysicalDeviceVulkan12Features*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceVulkan12Features->shaderFloat16 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceVulkan12Features->shaderFloat16 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceVulkan12Features::shaderFloat16 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceVulkan12Features->shaderInt8 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceVulkan12Features->shaderInt8 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceVulkan12Features::shaderInt8 == VK_TRUE"); + VkPhysicalDeviceVulkan12Features* s = static_cast<VkPhysicalDeviceVulkan12Features*>(static_cast<void*>(p)); + ret = ret && (s->shaderFloat16 == VK_TRUE); + ret = ret && (s->shaderInt8 == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: { - VkPhysicalDeviceCustomBorderColorFeaturesEXT* prettify_VkPhysicalDeviceCustomBorderColorFeaturesEXT = static_cast<VkPhysicalDeviceCustomBorderColorFeaturesEXT*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceCustomBorderColorFeaturesEXT->customBorderColors == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceCustomBorderColorFeaturesEXT->customBorderColors == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceCustomBorderColorFeaturesEXT::customBorderColors == VK_TRUE"); + VkPhysicalDeviceCustomBorderColorFeaturesEXT* s = static_cast<VkPhysicalDeviceCustomBorderColorFeaturesEXT*>(static_cast<void*>(p)); + ret = ret && (s->customBorderColors == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT: { - VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT* prettify_VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT = static_cast<VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT->primitiveTopologyListRestart == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT->primitiveTopologyListRestart == VK_TRUE), "Unsupported feature condition: VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT::primitiveTopologyListRestart == VK_TRUE"); + VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT* s = static_cast<VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT*>(static_cast<void*>(p)); + ret = ret && (s->primitiveTopologyListRestart == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: { - VkPhysicalDeviceProvokingVertexFeaturesEXT* prettify_VkPhysicalDeviceProvokingVertexFeaturesEXT = static_cast<VkPhysicalDeviceProvokingVertexFeaturesEXT*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceProvokingVertexFeaturesEXT->provokingVertexLast == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProvokingVertexFeaturesEXT->provokingVertexLast == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceProvokingVertexFeaturesEXT::provokingVertexLast == VK_TRUE"); + VkPhysicalDeviceProvokingVertexFeaturesEXT* s = static_cast<VkPhysicalDeviceProvokingVertexFeaturesEXT*>(static_cast<void*>(p)); + ret = ret && (s->provokingVertexLast == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: { - VkPhysicalDeviceIndexTypeUint8FeaturesEXT* prettify_VkPhysicalDeviceIndexTypeUint8FeaturesEXT = static_cast<VkPhysicalDeviceIndexTypeUint8FeaturesEXT*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceIndexTypeUint8FeaturesEXT->indexTypeUint8 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceIndexTypeUint8FeaturesEXT->indexTypeUint8 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceIndexTypeUint8FeaturesEXT::indexTypeUint8 == VK_TRUE"); + VkPhysicalDeviceIndexTypeUint8FeaturesEXT* s = static_cast<VkPhysicalDeviceIndexTypeUint8FeaturesEXT*>(static_cast<void*>(p)); + ret = ret && (s->indexTypeUint8 == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_KHR: { - VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR* prettify_VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR = static_cast<VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR->vertexAttributeInstanceRateDivisor == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR->vertexAttributeInstanceRateDivisor == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR::vertexAttributeInstanceRateDivisor == VK_TRUE"); + VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR* s = static_cast<VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR*>(static_cast<void*>(p)); + ret = ret && (s->vertexAttributeInstanceRateDivisor == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: { - VkPhysicalDeviceSamplerYcbcrConversionFeatures* prettify_VkPhysicalDeviceSamplerYcbcrConversionFeatures = static_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceSamplerYcbcrConversionFeatures->samplerYcbcrConversion == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceSamplerYcbcrConversionFeatures->samplerYcbcrConversion == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceSamplerYcbcrConversionFeatures::samplerYcbcrConversion == VK_TRUE"); + VkPhysicalDeviceSamplerYcbcrConversionFeatures* s = static_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(static_cast<void*>(p)); + ret = ret && (s->samplerYcbcrConversion == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES: { - VkPhysicalDeviceShaderFloat16Int8Features* prettify_VkPhysicalDeviceShaderFloat16Int8Features = static_cast<VkPhysicalDeviceShaderFloat16Int8Features*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceShaderFloat16Int8Features->shaderFloat16 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceShaderFloat16Int8Features->shaderFloat16 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceShaderFloat16Int8Features::shaderFloat16 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceShaderFloat16Int8Features->shaderInt8 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceShaderFloat16Int8Features->shaderInt8 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceShaderFloat16Int8Features::shaderInt8 == VK_TRUE"); + VkPhysicalDeviceShaderFloat16Int8Features* s = static_cast<VkPhysicalDeviceShaderFloat16Int8Features*>(static_cast<void*>(p)); + ret = ret && (s->shaderFloat16 == VK_TRUE); + ret = ret && (s->shaderInt8 == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES: { - VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures* prettify_VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures = static_cast<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures->shaderSubgroupExtendedTypes == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures->shaderSubgroupExtendedTypes == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures::shaderSubgroupExtendedTypes == VK_TRUE"); + VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures* s = static_cast<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures*>(static_cast<void*>(p)); + ret = ret && (s->shaderSubgroupExtendedTypes == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES: { - VkPhysicalDevice8BitStorageFeatures* prettify_VkPhysicalDevice8BitStorageFeatures = static_cast<VkPhysicalDevice8BitStorageFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDevice8BitStorageFeatures->storageBuffer8BitAccess == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDevice8BitStorageFeatures->storageBuffer8BitAccess == VK_TRUE), "Unsupported feature condition: VkPhysicalDevice8BitStorageFeatures::storageBuffer8BitAccess == VK_TRUE"); + VkPhysicalDevice8BitStorageFeatures* s = static_cast<VkPhysicalDevice8BitStorageFeatures*>(static_cast<void*>(p)); + ret = ret && (s->storageBuffer8BitAccess == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: { - VkPhysicalDevice16BitStorageFeatures* prettify_VkPhysicalDevice16BitStorageFeatures = static_cast<VkPhysicalDevice16BitStorageFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDevice16BitStorageFeatures->storageBuffer16BitAccess == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDevice16BitStorageFeatures->storageBuffer16BitAccess == VK_TRUE), "Unsupported feature condition: VkPhysicalDevice16BitStorageFeatures::storageBuffer16BitAccess == VK_TRUE"); + VkPhysicalDevice16BitStorageFeatures* s = static_cast<VkPhysicalDevice16BitStorageFeatures*>(static_cast<void*>(p)); + ret = ret && (s->storageBuffer16BitAccess == VK_TRUE); } break; default: break; } @@ -430,7 +610,7 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); @@ -447,20 +627,20 @@ static const VpPropertyDesc propertyDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { - VkPhysicalDeviceProperties2KHR* prettify_VkPhysicalDeviceProperties2KHR = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxColorAttachments >= 8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxColorAttachments >= 8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxColorAttachments >= 8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSampledImages >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSampledImages >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorSampledImages >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSamplers >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSamplers >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorSamplers >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageBuffers >= 12); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageBuffers >= 12), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorStorageBuffers >= 12"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorUniformBuffers >= 13); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorUniformBuffers >= 13), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorUniformBuffers >= 13"); + VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (s->properties.limits.maxColorAttachments >= 8); + ret = ret && (s->properties.limits.maxPerStageDescriptorSampledImages >= 128); + ret = ret && (s->properties.limits.maxPerStageDescriptorSamplers >= 128); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageBuffers >= 12); + ret = ret && (s->properties.limits.maxPerStageDescriptorUniformBuffers >= 13); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES: { - VkPhysicalDeviceVulkan11Properties* prettify_VkPhysicalDeviceVulkan11Properties = static_cast<VkPhysicalDeviceVulkan11Properties*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceVulkan11Properties->subgroupSupportedOperations, (VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceVulkan11Properties->subgroupSupportedOperations, (VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT))), "Unsupported properties condition: VkPhysicalDeviceVulkan11Properties::subgroupSupportedOperations contains (VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT)"); + VkPhysicalDeviceVulkan11Properties* s = static_cast<VkPhysicalDeviceVulkan11Properties*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->subgroupSupportedOperations, (VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT))); } break; default: break; } @@ -471,7 +651,7 @@ static const VpPropertyDesc propertyDesc = { static const VpFormatDesc formatDesc[] = { { VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -481,13 +661,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -496,7 +676,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -506,13 +686,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -545,8 +725,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceVulkan11Properties)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -554,14 +734,15 @@ static const VpStructChainerDesc chainerDesc = { pfnCb(p, pUser); }, }; -} //namespace MUST +} // namespace MUST namespace primitivesGeneratedQuery { + static const VkExtensionProperties deviceExtensions[] = { VkExtensionProperties{ VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME, 1 }, }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT: { VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT* s = static_cast<VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT*>(static_cast<void*>(p)); @@ -570,12 +751,12 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT: { - VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT* prettify_VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT = static_cast<VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT->primitivesGeneratedQuery == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT->primitivesGeneratedQuery == VK_TRUE), "Unsupported feature condition: VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT::primitivesGeneratedQuery == VK_TRUE"); + VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT* s = static_cast<VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT*>(static_cast<void*>(p)); + ret = ret && (s->primitivesGeneratedQuery == VK_TRUE); } break; default: break; } @@ -584,9 +765,9 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; return ret; } @@ -616,8 +797,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceVulkan11Properties)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -625,10 +806,11 @@ static const VpStructChainerDesc chainerDesc = { pfnCb(p, pUser); }, }; -} //namespace primitivesGeneratedQuery +} // namespace primitivesGeneratedQuery namespace pipelineStatisticsQuery { + static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); @@ -637,12 +819,12 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { - VkPhysicalDeviceFeatures2KHR* prettify_VkPhysicalDeviceFeatures2KHR = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.pipelineStatisticsQuery == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.pipelineStatisticsQuery == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.pipelineStatisticsQuery == VK_TRUE"); + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + ret = ret && (s->features.pipelineStatisticsQuery == VK_TRUE); } break; default: break; } @@ -651,9 +833,9 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; return ret; } @@ -683,8 +865,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceVulkan11Properties)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -692,14 +874,15 @@ static const VpStructChainerDesc chainerDesc = { pfnCb(p, pUser); }, }; -} //namespace pipelineStatisticsQuery +} // namespace pipelineStatisticsQuery namespace swBresenhamLines { + static const VkExtensionProperties deviceExtensions[] = { VkExtensionProperties{ VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, 1 }, }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: { VkPhysicalDeviceLineRasterizationFeaturesEXT* s = static_cast<VkPhysicalDeviceLineRasterizationFeaturesEXT*>(static_cast<void*>(p)); @@ -708,12 +891,12 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: { - VkPhysicalDeviceLineRasterizationFeaturesEXT* prettify_VkPhysicalDeviceLineRasterizationFeaturesEXT = static_cast<VkPhysicalDeviceLineRasterizationFeaturesEXT*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceLineRasterizationFeaturesEXT->bresenhamLines == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceLineRasterizationFeaturesEXT->bresenhamLines == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceLineRasterizationFeaturesEXT::bresenhamLines == VK_TRUE"); + VkPhysicalDeviceLineRasterizationFeaturesEXT* s = static_cast<VkPhysicalDeviceLineRasterizationFeaturesEXT*>(static_cast<void*>(p)); + ret = ret && (s->bresenhamLines == VK_TRUE); } break; default: break; } @@ -722,9 +905,9 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; return ret; } @@ -754,8 +937,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceVulkan11Properties)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -763,14 +946,15 @@ static const VpStructChainerDesc chainerDesc = { pfnCb(p, pUser); }, }; -} //namespace swBresenhamLines +} // namespace swBresenhamLines namespace hwBresenhamLines { + static const VkExtensionProperties deviceExtensions[] = { VkExtensionProperties{ VK_IMG_RELAXED_LINE_RASTERIZATION_EXTENSION_NAME, 1 }, }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG: { VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG* s = static_cast<VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG*>(static_cast<void*>(p)); @@ -779,12 +963,12 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG: { - VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG* prettify_VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG = static_cast<VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG->relaxedLineRasterization == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG->relaxedLineRasterization == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG::relaxedLineRasterization == VK_TRUE"); + VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG* s = static_cast<VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG*>(static_cast<void*>(p)); + ret = ret && (s->relaxedLineRasterization == VK_TRUE); } break; default: break; } @@ -793,9 +977,9 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; return ret; } @@ -825,8 +1009,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceVulkan11Properties)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -834,10 +1018,343 @@ static const VpStructChainerDesc chainerDesc = { pfnCb(p, pUser); }, }; -} //namespace hwBresenhamLines +} // namespace hwBresenhamLines +} // namespace blocks } // namespace VP_ANDROID_15_MINIMUMS #endif // VP_ANDROID_15_minimums +#ifdef VP_ANDROID_16_minimums +namespace VP_ANDROID_16_MINIMUMS { + +static const VkStructureType featureStructTypes[] = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, +}; + +static const VkStructureType propertyStructTypes[] = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, +}; + +namespace blocks { +namespace MUST { + +static const VkExtensionProperties deviceExtensions[] = { + VkExtensionProperties{ VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_8BIT_STORAGE_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_LOAD_STORE_OP_NONE_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_MAINTENANCE_6_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_MAP_MEMORY_2_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SHADER_FLOAT_CONTROLS_2_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SHADER_MAXIMAL_RECONVERGENCE_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SHADER_SUBGROUP_ROTATE_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, 1 }, +}; + +static const VpFeatureDesc featureDesc = { + [](VkBaseOutStructure* p) { (void)p; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + s->features.fullDrawIndexUint32 = VK_TRUE; + s->features.shaderInt16 = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast<VkPhysicalDeviceVulkan12Features*>(static_cast<void*>(p)); + s->samplerMirrorClampToEdge = VK_TRUE; + s->scalarBlockLayout = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: { + VkPhysicalDeviceProtectedMemoryFeatures* s = static_cast<VkPhysicalDeviceProtectedMemoryFeatures*>(static_cast<void*>(p)); + s->protectedMemory = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES: { + VkPhysicalDeviceShaderIntegerDotProductFeatures* s = static_cast<VkPhysicalDeviceShaderIntegerDotProductFeatures*>(static_cast<void*>(p)); + s->shaderIntegerDotProduct = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: { + VkPhysicalDeviceTransformFeedbackFeaturesEXT* s = static_cast<VkPhysicalDeviceTransformFeedbackFeaturesEXT*>(static_cast<void*>(p)); + s->transformFeedback = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT: { + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT* s = static_cast<VkPhysicalDeviceImage2DViewOf3DFeaturesEXT*>(static_cast<void*>(p)); + s->image2DViewOf3D = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR: { + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR* s = static_cast<VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR*>(static_cast<void*>(p)); + s->shaderSubgroupUniformControlFlow = VK_TRUE; + } break; + default: break; + } + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.shaderInt16 == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast<VkPhysicalDeviceVulkan12Features*>(static_cast<void*>(p)); + ret = ret && (s->samplerMirrorClampToEdge == VK_TRUE); + ret = ret && (s->scalarBlockLayout == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: { + VkPhysicalDeviceProtectedMemoryFeatures* s = static_cast<VkPhysicalDeviceProtectedMemoryFeatures*>(static_cast<void*>(p)); + ret = ret && (s->protectedMemory == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES: { + VkPhysicalDeviceShaderIntegerDotProductFeatures* s = static_cast<VkPhysicalDeviceShaderIntegerDotProductFeatures*>(static_cast<void*>(p)); + ret = ret && (s->shaderIntegerDotProduct == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: { + VkPhysicalDeviceTransformFeedbackFeaturesEXT* s = static_cast<VkPhysicalDeviceTransformFeedbackFeaturesEXT*>(static_cast<void*>(p)); + ret = ret && (s->transformFeedback == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT: { + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT* s = static_cast<VkPhysicalDeviceImage2DViewOf3DFeaturesEXT*>(static_cast<void*>(p)); + ret = ret && (s->image2DViewOf3D == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR: { + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR* s = static_cast<VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR*>(static_cast<void*>(p)); + ret = ret && (s->shaderSubgroupUniformControlFlow == VK_TRUE); + } break; + default: break; + } + return ret; + } +}; + +static const VpPropertyDesc propertyDesc = { + [](VkBaseOutStructure* p) { (void)p; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { + VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); + s->properties.limits.bufferImageGranularity = 4096; + s->properties.limits.lineWidthGranularity = 0.5f; + s->properties.limits.maxColorAttachments = 8; + s->properties.limits.maxComputeWorkGroupInvocations = 256; + s->properties.limits.maxComputeWorkGroupSize[0] = 256; + s->properties.limits.maxComputeWorkGroupSize[1] = 256; + s->properties.limits.maxComputeWorkGroupSize[2] = 64; + s->properties.limits.maxDescriptorSetStorageBuffers = 96; + s->properties.limits.maxDescriptorSetUniformBuffers = 90; + s->properties.limits.maxFragmentCombinedOutputResources = 16; + s->properties.limits.maxImageArrayLayers = 2048; + s->properties.limits.maxImageDimension1D = 8192; + s->properties.limits.maxImageDimension2D = 8192; + s->properties.limits.maxImageDimensionCube = 8192; + s->properties.limits.maxPerStageDescriptorUniformBuffers = 15; + s->properties.limits.maxPerStageResources = 200; + s->properties.limits.maxSamplerLodBias = 14; + s->properties.limits.maxUniformBufferRange = 65536; + s->properties.limits.maxVertexOutputComponents = 72; + s->properties.limits.mipmapPrecisionBits = 6; + s->properties.limits.pointSizeGranularity = 0.125f; + s->properties.limits.standardSampleLocations = VK_TRUE; + s->properties.limits.subTexelPrecisionBits = 8; + s->properties.limits.timestampComputeAndGraphics = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES: { + VkPhysicalDeviceFloatControlsProperties* s = static_cast<VkPhysicalDeviceFloatControlsProperties*>(static_cast<void*>(p)); + s->shaderSignedZeroInfNanPreserveFloat16 = VK_TRUE; + s->shaderSignedZeroInfNanPreserveFloat32 = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES: { + VkPhysicalDeviceVulkan11Properties* s = static_cast<VkPhysicalDeviceVulkan11Properties*>(static_cast<void*>(p)); + s->subgroupSupportedStages |= (VK_SHADER_STAGE_COMPUTE_BIT); + } break; + default: break; + } + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { + VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (s->properties.limits.bufferImageGranularity <= 4096); + ret = ret && ((4096 % s->properties.limits.bufferImageGranularity) == 0); + ret = ret && (s->properties.limits.lineWidthGranularity <= 0.5); + ret = ret && (isMultiple(0.5, s->properties.limits.lineWidthGranularity)); + ret = ret && (s->properties.limits.maxColorAttachments >= 8); + ret = ret && (s->properties.limits.maxComputeWorkGroupInvocations >= 256); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[0] >= 256); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[1] >= 256); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[2] >= 64); + ret = ret && (s->properties.limits.maxDescriptorSetStorageBuffers >= 96); + ret = ret && (s->properties.limits.maxDescriptorSetUniformBuffers >= 90); + ret = ret && (s->properties.limits.maxFragmentCombinedOutputResources >= 16); + ret = ret && (s->properties.limits.maxImageArrayLayers >= 2048); + ret = ret && (s->properties.limits.maxImageDimension1D >= 8192); + ret = ret && (s->properties.limits.maxImageDimension2D >= 8192); + ret = ret && (s->properties.limits.maxImageDimensionCube >= 8192); + ret = ret && (s->properties.limits.maxPerStageDescriptorUniformBuffers >= 15); + ret = ret && (s->properties.limits.maxPerStageResources >= 200); + ret = ret && (s->properties.limits.maxSamplerLodBias >= 14); + ret = ret && (s->properties.limits.maxUniformBufferRange >= 65536); + ret = ret && (s->properties.limits.maxVertexOutputComponents >= 72); + ret = ret && (s->properties.limits.mipmapPrecisionBits >= 6); + ret = ret && (s->properties.limits.pointSizeGranularity <= 0.125); + ret = ret && (isMultiple(0.125, s->properties.limits.pointSizeGranularity)); + ret = ret && (s->properties.limits.standardSampleLocations == VK_TRUE); + ret = ret && (s->properties.limits.subTexelPrecisionBits >= 8); + ret = ret && (vpCheckFlags(s->properties.limits.timestampComputeAndGraphics, VK_TRUE)); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES: { + VkPhysicalDeviceFloatControlsProperties* s = static_cast<VkPhysicalDeviceFloatControlsProperties*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->shaderSignedZeroInfNanPreserveFloat16, VK_TRUE)); + ret = ret && (vpCheckFlags(s->shaderSignedZeroInfNanPreserveFloat32, VK_TRUE)); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES: { + VkPhysicalDeviceVulkan11Properties* s = static_cast<VkPhysicalDeviceVulkan11Properties*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->subgroupSupportedStages, (VK_SHADER_STAGE_COMPUTE_BIT))); + } break; + default: break; + } + return ret; + } +}; + +static const VpStructChainerDesc chainerDesc = { + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr }; + VkPhysicalDeviceProtectedMemoryFeatures physicalDeviceProtectedMemoryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, &physicalDeviceVulkan12Features }; + VkPhysicalDeviceShaderIntegerDotProductFeatures physicalDeviceShaderIntegerDotProductFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, &physicalDeviceProtectedMemoryFeatures }; + VkPhysicalDeviceTransformFeedbackFeaturesEXT physicalDeviceTransformFeedbackFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, &physicalDeviceShaderIntegerDotProductFeatures }; + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT physicalDeviceImage2DViewOf3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, &physicalDeviceTransformFeedbackFeaturesEXT }; + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, &physicalDeviceImage2DViewOf3DFeaturesEXT }; + p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR)); + pfnCb(p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceFloatControlsProperties physicalDeviceFloatControlsProperties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, nullptr }; + VkPhysicalDeviceVulkan11Properties physicalDeviceVulkan11Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, &physicalDeviceFloatControlsProperties }; + p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceVulkan11Properties)); + pfnCb(p, pUser); + }, + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + pfnCb(p, pUser); + }, +}; +} // namespace MUST +namespace multisampledToSingleSampled { + +static const VkExtensionProperties deviceExtensions[] = { + VkExtensionProperties{ VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME, 1 }, +}; + +static const VpFeatureDesc featureDesc = { + [](VkBaseOutStructure* p) { (void)p; + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + return ret; + } +}; + +static const VpPropertyDesc propertyDesc = { + [](VkBaseOutStructure* p) { (void)p; + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + return ret; + } +}; + +static const VpStructChainerDesc chainerDesc = { + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr }; + VkPhysicalDeviceProtectedMemoryFeatures physicalDeviceProtectedMemoryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, &physicalDeviceVulkan12Features }; + VkPhysicalDeviceShaderIntegerDotProductFeatures physicalDeviceShaderIntegerDotProductFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, &physicalDeviceProtectedMemoryFeatures }; + VkPhysicalDeviceTransformFeedbackFeaturesEXT physicalDeviceTransformFeedbackFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, &physicalDeviceShaderIntegerDotProductFeatures }; + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT physicalDeviceImage2DViewOf3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, &physicalDeviceTransformFeedbackFeaturesEXT }; + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, &physicalDeviceImage2DViewOf3DFeaturesEXT }; + p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR)); + pfnCb(p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceFloatControlsProperties physicalDeviceFloatControlsProperties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, nullptr }; + VkPhysicalDeviceVulkan11Properties physicalDeviceVulkan11Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, &physicalDeviceFloatControlsProperties }; + p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceVulkan11Properties)); + pfnCb(p, pUser); + }, + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + pfnCb(p, pUser); + }, +}; +} // namespace multisampledToSingleSampled +namespace shaderStencilExport { + +static const VkExtensionProperties deviceExtensions[] = { + VkExtensionProperties{ VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, 1 }, +}; + +static const VpFeatureDesc featureDesc = { + [](VkBaseOutStructure* p) { (void)p; + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + return ret; + } +}; + +static const VpPropertyDesc propertyDesc = { + [](VkBaseOutStructure* p) { (void)p; + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + return ret; + } +}; + +static const VpStructChainerDesc chainerDesc = { + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr }; + VkPhysicalDeviceProtectedMemoryFeatures physicalDeviceProtectedMemoryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, &physicalDeviceVulkan12Features }; + VkPhysicalDeviceShaderIntegerDotProductFeatures physicalDeviceShaderIntegerDotProductFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, &physicalDeviceProtectedMemoryFeatures }; + VkPhysicalDeviceTransformFeedbackFeaturesEXT physicalDeviceTransformFeedbackFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, &physicalDeviceShaderIntegerDotProductFeatures }; + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT physicalDeviceImage2DViewOf3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, &physicalDeviceTransformFeedbackFeaturesEXT }; + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, &physicalDeviceImage2DViewOf3DFeaturesEXT }; + p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR)); + pfnCb(p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceFloatControlsProperties physicalDeviceFloatControlsProperties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, nullptr }; + VkPhysicalDeviceVulkan11Properties physicalDeviceVulkan11Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, &physicalDeviceFloatControlsProperties }; + p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceVulkan11Properties)); + pfnCb(p, pUser); + }, + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + pfnCb(p, pUser); + }, +}; +} // namespace shaderStencilExport +} // namespace blocks +} // namespace VP_ANDROID_16_MINIMUMS +#endif // VP_ANDROID_16_minimums + #ifdef VP_ANDROID_baseline_2021 namespace VP_ANDROID_BASELINE_2021 { @@ -883,7 +1400,7 @@ static const VkExtensionProperties deviceExtensions[] = { }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); @@ -903,23 +1420,23 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { - VkPhysicalDeviceFeatures2KHR* prettify_VkPhysicalDeviceFeatures2KHR = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.depthBiasClamp == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fragmentStoresAndAtomics == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fullDrawIndexUint32 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.imageCubeArray == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.independentBlend == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.robustBufferAccess == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.sampleRateShading == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderSampledImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionASTC_LDR == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionETC2 == VK_TRUE"); + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.textureCompressionASTC_LDR == VK_TRUE); + ret = ret && (s->features.textureCompressionETC2 == VK_TRUE); } break; default: break; } @@ -928,9 +1445,9 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; return ret; } @@ -945,8 +1462,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(nullptr)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -955,7 +1472,9 @@ static const VpStructChainerDesc chainerDesc = { }, }; +namespace blocks { namespace baseline { + static const VkExtensionProperties instanceExtensions[] = { VkExtensionProperties{ VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, 1 }, VkExtensionProperties{ VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 1 }, @@ -985,7 +1504,7 @@ static const VkExtensionProperties deviceExtensions[] = { }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); @@ -1005,23 +1524,23 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { - VkPhysicalDeviceFeatures2KHR* prettify_VkPhysicalDeviceFeatures2KHR = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.depthBiasClamp == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fragmentStoresAndAtomics == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fullDrawIndexUint32 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.imageCubeArray == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.independentBlend == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.robustBufferAccess == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.sampleRateShading == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderSampledImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionASTC_LDR == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionETC2 == VK_TRUE"); + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.textureCompressionASTC_LDR == VK_TRUE); + ret = ret && (s->features.textureCompressionETC2 == VK_TRUE); } break; default: break; } @@ -1030,7 +1549,7 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); @@ -1119,97 +1638,97 @@ static const VpPropertyDesc propertyDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { - VkPhysicalDeviceProperties2KHR* prettify_VkPhysicalDeviceProperties2KHR = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.discreteQueuePriorities >= 2); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.discreteQueuePriorities >= 2), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.discreteQueuePriorities >= 2"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferColorSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferDepthSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferNoAttachmentsSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferNoAttachmentsSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferNoAttachmentsSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferStencilSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxBoundDescriptorSets >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxBoundDescriptorSets >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxBoundDescriptorSets >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxColorAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxColorAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxColorAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeSharedMemorySize >= 16384); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeSharedMemorySize >= 16384), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeSharedMemorySize >= 16384"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[0] >= 65535); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[0] >= 65535), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupCount[0] >= 65535"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[1] >= 65535); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[1] >= 65535), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupCount[1] >= 65535"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[2] >= 65535); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[2] >= 65535), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupCount[2] >= 65535"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupInvocations >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupInvocations >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupInvocations >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[0] >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[0] >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupSize[0] >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[1] >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[1] >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupSize[1] >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[2] >= 64); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[2] >= 64), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupSize[2] >= 64"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetInputAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetInputAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetInputAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSampledImages >= 48); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSampledImages >= 48), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetSampledImages >= 48"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSamplers >= 48); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSamplers >= 48), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetSamplers >= 48"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffers >= 24); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffers >= 24), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetStorageBuffers >= 24"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageImages >= 12); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageImages >= 12), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetStorageImages >= 12"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffers >= 36); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffers >= 36), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetUniformBuffers >= 36"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndexedIndexValue >= 4294967295); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndexedIndexValue >= 4294967295), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDrawIndexedIndexValue >= 4294967295"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndirectCount >= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndirectCount >= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDrawIndirectCount >= 1"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentCombinedOutputResources >= 8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentCombinedOutputResources >= 8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFragmentCombinedOutputResources >= 8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentInputComponents >= 64); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentInputComponents >= 64), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFragmentInputComponents >= 64"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentOutputAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentOutputAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFragmentOutputAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferHeight >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferHeight >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFramebufferHeight >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferLayers >= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferLayers >= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFramebufferLayers >= 256"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferWidth >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferWidth >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFramebufferWidth >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageArrayLayers >= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageArrayLayers >= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageArrayLayers >= 256"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension1D >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension1D >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimension1D >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension2D >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension2D >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimension2D >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension3D >= 512); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension3D >= 512), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimension3D >= 512"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimensionCube >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimensionCube >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimensionCube >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxInterpolationOffset >= 0.4375); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxInterpolationOffset >= 0.4375), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxInterpolationOffset >= 0.4375"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxMemoryAllocationCount >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxMemoryAllocationCount >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxMemoryAllocationCount >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorInputAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorInputAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorInputAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSampledImages >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSampledImages >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorSampledImages >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSamplers >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSamplers >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorSamplers >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageBuffers >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageBuffers >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorStorageBuffers >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageImages >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageImages >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorStorageImages >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorUniformBuffers >= 12); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorUniformBuffers >= 12), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorUniformBuffers >= 12"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageResources >= 44); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageResources >= 44), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageResources >= 44"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPushConstantsSize >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPushConstantsSize >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPushConstantsSize >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSampleMaskWords >= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSampleMaskWords >= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSampleMaskWords >= 1"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAllocationCount >= 4000); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAllocationCount >= 4000), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSamplerAllocationCount >= 4000"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAnisotropy >= 1.0); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAnisotropy >= 1.0), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSamplerAnisotropy >= 1.0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerLodBias >= 2.0); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerLodBias >= 2.0), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSamplerLodBias >= 2.0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxStorageBufferRange >= 134217728); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxStorageBufferRange >= 134217728), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxStorageBufferRange >= 134217728"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelBufferElements >= 65536); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelBufferElements >= 65536), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxTexelBufferElements >= 65536"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelOffset >= 7); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelOffset >= 7), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxTexelOffset >= 7"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxUniformBufferRange >= 16384); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxUniformBufferRange >= 16384), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxUniformBufferRange >= 16384"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributeOffset >= 2047); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributeOffset >= 2047), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputAttributeOffset >= 2047"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributes >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributes >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputAttributes >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindingStride >= 2048); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindingStride >= 2048), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputBindingStride >= 2048"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindings >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindings >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputBindings >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexOutputComponents >= 64); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexOutputComponents >= 64), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexOutputComponents >= 64"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[0] >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[0] >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxViewportDimensions[0] >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[1] >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[1] >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxViewportDimensions[1] >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewports >= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewports >= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxViewports >= 1"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minInterpolationOffset <= -0.5); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minInterpolationOffset <= -0.5), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minInterpolationOffset <= -0.5"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment <= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment <= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minMemoryMapAlignment <= 4096"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment <= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment <= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minStorageBufferOffsetAlignment <= 256"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment <= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment <= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minTexelBufferOffsetAlignment <= 256"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelOffset <= -8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelOffset <= -8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minTexelOffset <= -8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment <= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment <= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minUniformBufferOffsetAlignment <= 256"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.mipmapPrecisionBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.mipmapPrecisionBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.mipmapPrecisionBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity <= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity <= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.pointSizeGranularity <= 1"); - ret = ret && (isMultiple(1, prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity)); VP_DEBUG_COND_MSG(!(isMultiple(1, prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity)), "Unsupported properties condition: isMultiple(1, prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageColorSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageDepthSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageIntegerSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageIntegerSampleCounts, (VK_SAMPLE_COUNT_1_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageIntegerSampleCounts contains (VK_SAMPLE_COUNT_1_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageStencilSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.standardSampleLocations == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.standardSampleLocations == VK_TRUE), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.standardSampleLocations == VK_TRUE"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.storageImageSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.storageImageSampleCounts, (VK_SAMPLE_COUNT_1_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.storageImageSampleCounts contains (VK_SAMPLE_COUNT_1_BIT)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelInterpolationOffsetBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelInterpolationOffsetBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.subPixelInterpolationOffsetBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelPrecisionBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelPrecisionBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.subPixelPrecisionBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subTexelPrecisionBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subTexelPrecisionBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.subTexelPrecisionBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[0] <= -8192); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[0] <= -8192), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.viewportBoundsRange[0] <= -8192"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[1] >= 8191); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[1] >= 8191), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.viewportBoundsRange[1] >= 8191"); + VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (s->properties.limits.discreteQueuePriorities >= 2); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferNoAttachmentsSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (s->properties.limits.maxBoundDescriptorSets >= 4); + ret = ret && (s->properties.limits.maxColorAttachments >= 4); + ret = ret && (s->properties.limits.maxComputeSharedMemorySize >= 16384); + ret = ret && (s->properties.limits.maxComputeWorkGroupCount[0] >= 65535); + ret = ret && (s->properties.limits.maxComputeWorkGroupCount[1] >= 65535); + ret = ret && (s->properties.limits.maxComputeWorkGroupCount[2] >= 65535); + ret = ret && (s->properties.limits.maxComputeWorkGroupInvocations >= 128); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[0] >= 128); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[1] >= 128); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[2] >= 64); + ret = ret && (s->properties.limits.maxDescriptorSetInputAttachments >= 4); + ret = ret && (s->properties.limits.maxDescriptorSetSampledImages >= 48); + ret = ret && (s->properties.limits.maxDescriptorSetSamplers >= 48); + ret = ret && (s->properties.limits.maxDescriptorSetStorageBuffers >= 24); + ret = ret && (s->properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4); + ret = ret && (s->properties.limits.maxDescriptorSetStorageImages >= 12); + ret = ret && (s->properties.limits.maxDescriptorSetUniformBuffers >= 36); + ret = ret && (s->properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8); + ret = ret && (s->properties.limits.maxDrawIndexedIndexValue >= 4294967295); + ret = ret && (s->properties.limits.maxDrawIndirectCount >= 1); + ret = ret && (s->properties.limits.maxFragmentCombinedOutputResources >= 8); + ret = ret && (s->properties.limits.maxFragmentInputComponents >= 64); + ret = ret && (s->properties.limits.maxFragmentOutputAttachments >= 4); + ret = ret && (s->properties.limits.maxFramebufferHeight >= 4096); + ret = ret && (s->properties.limits.maxFramebufferLayers >= 256); + ret = ret && (s->properties.limits.maxFramebufferWidth >= 4096); + ret = ret && (s->properties.limits.maxImageArrayLayers >= 256); + ret = ret && (s->properties.limits.maxImageDimension1D >= 4096); + ret = ret && (s->properties.limits.maxImageDimension2D >= 4096); + ret = ret && (s->properties.limits.maxImageDimension3D >= 512); + ret = ret && (s->properties.limits.maxImageDimensionCube >= 4096); + ret = ret && (s->properties.limits.maxInterpolationOffset >= 0.4375); + ret = ret && (s->properties.limits.maxMemoryAllocationCount >= 4096); + ret = ret && (s->properties.limits.maxPerStageDescriptorInputAttachments >= 4); + ret = ret && (s->properties.limits.maxPerStageDescriptorSampledImages >= 16); + ret = ret && (s->properties.limits.maxPerStageDescriptorSamplers >= 16); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageBuffers >= 4); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageImages >= 4); + ret = ret && (s->properties.limits.maxPerStageDescriptorUniformBuffers >= 12); + ret = ret && (s->properties.limits.maxPerStageResources >= 44); + ret = ret && (s->properties.limits.maxPushConstantsSize >= 128); + ret = ret && (s->properties.limits.maxSampleMaskWords >= 1); + ret = ret && (s->properties.limits.maxSamplerAllocationCount >= 4000); + ret = ret && (s->properties.limits.maxSamplerAnisotropy >= 1.0); + ret = ret && (s->properties.limits.maxSamplerLodBias >= 2.0); + ret = ret && (s->properties.limits.maxStorageBufferRange >= 134217728); + ret = ret && (s->properties.limits.maxTexelBufferElements >= 65536); + ret = ret && (s->properties.limits.maxTexelOffset >= 7); + ret = ret && (s->properties.limits.maxUniformBufferRange >= 16384); + ret = ret && (s->properties.limits.maxVertexInputAttributeOffset >= 2047); + ret = ret && (s->properties.limits.maxVertexInputAttributes >= 16); + ret = ret && (s->properties.limits.maxVertexInputBindingStride >= 2048); + ret = ret && (s->properties.limits.maxVertexInputBindings >= 16); + ret = ret && (s->properties.limits.maxVertexOutputComponents >= 64); + ret = ret && (s->properties.limits.maxViewportDimensions[0] >= 4096); + ret = ret && (s->properties.limits.maxViewportDimensions[1] >= 4096); + ret = ret && (s->properties.limits.maxViewports >= 1); + ret = ret && (s->properties.limits.minInterpolationOffset <= -0.5); + ret = ret && (s->properties.limits.minMemoryMapAlignment <= 4096); + ret = ret && ((s->properties.limits.minMemoryMapAlignment & (s->properties.limits.minMemoryMapAlignment - 1)) == 0); + ret = ret && (s->properties.limits.minStorageBufferOffsetAlignment <= 256); + ret = ret && ((s->properties.limits.minStorageBufferOffsetAlignment & (s->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0); + ret = ret && (s->properties.limits.minTexelBufferOffsetAlignment <= 256); + ret = ret && ((s->properties.limits.minTexelBufferOffsetAlignment & (s->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0); + ret = ret && (s->properties.limits.minTexelOffset <= -8); + ret = ret && (s->properties.limits.minUniformBufferOffsetAlignment <= 256); + ret = ret && ((s->properties.limits.minUniformBufferOffsetAlignment & (s->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0); + ret = ret && (s->properties.limits.mipmapPrecisionBits >= 4); + ret = ret && (s->properties.limits.pointSizeGranularity <= 1); + ret = ret && (isMultiple(1, s->properties.limits.pointSizeGranularity)); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageIntegerSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (s->properties.limits.standardSampleLocations == VK_TRUE); + ret = ret && (vpCheckFlags(s->properties.limits.storageImageSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); + ret = ret && (s->properties.limits.subPixelInterpolationOffsetBits >= 4); + ret = ret && (s->properties.limits.subPixelPrecisionBits >= 4); + ret = ret && (s->properties.limits.subTexelPrecisionBits >= 4); + ret = ret && (s->properties.limits.viewportBoundsRange[0] <= -8192); + ret = ret && (s->properties.limits.viewportBoundsRange[1] >= 8191); } break; default: break; } @@ -1220,7 +1739,7 @@ static const VpPropertyDesc propertyDesc = { static const VpFormatDesc formatDesc[] = { { VK_FORMAT_A1R5G5B5_UNORM_PACK16, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1230,13 +1749,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A1R5G5B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A1R5G5B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1245,7 +1764,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A2B10G10R10_UINT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1256,14 +1775,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UINT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UINT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UINT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1272,7 +1791,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A2B10G10R10_UNORM_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1283,14 +1802,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1299,7 +1818,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_SINT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1310,14 +1829,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SINT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SINT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SINT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1326,7 +1845,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_SNORM_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1337,14 +1856,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SNORM_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SNORM_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SNORM_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1353,7 +1872,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_SRGB_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1363,13 +1882,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SRGB_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SRGB_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1378,7 +1897,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_UINT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1389,14 +1908,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UINT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UINT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UINT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1405,7 +1924,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_UNORM_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1416,14 +1935,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1432,7 +1951,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x10_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1442,13 +1961,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1457,7 +1976,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x10_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1467,13 +1986,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1482,7 +2001,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1492,13 +2011,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1507,7 +2026,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1517,13 +2036,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1532,7 +2051,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x6_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1542,13 +2061,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1557,7 +2076,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x6_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1567,13 +2086,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1582,7 +2101,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1592,13 +2111,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1607,7 +2126,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1617,13 +2136,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1632,7 +2151,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x10_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1642,13 +2161,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1657,7 +2176,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x10_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1667,13 +2186,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1682,7 +2201,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x12_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1692,13 +2211,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1707,7 +2226,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x12_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1717,13 +2236,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1732,7 +2251,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_4x4_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1742,13 +2261,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1757,7 +2276,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_4x4_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1767,13 +2286,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1782,7 +2301,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x4_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1792,13 +2311,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1807,7 +2326,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x4_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1817,13 +2336,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1832,7 +2351,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1842,13 +2361,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1857,7 +2376,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1867,13 +2386,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1882,7 +2401,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1892,13 +2411,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1907,7 +2426,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1917,13 +2436,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1932,7 +2451,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x6_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1942,13 +2461,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1957,7 +2476,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x6_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1967,13 +2486,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -1982,7 +2501,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -1992,13 +2511,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2007,7 +2526,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2017,13 +2536,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2032,7 +2551,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x6_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2042,13 +2561,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2057,7 +2576,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x6_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2067,13 +2586,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2082,7 +2601,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2092,13 +2611,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2107,7 +2626,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2117,13 +2636,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2132,7 +2651,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B10G11R11_UFLOAT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2143,14 +2662,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_B10G11R11_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B10G11R11_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B10G11R11_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2159,7 +2678,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B4G4R4A4_UNORM_PACK16, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2169,13 +2688,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B4G4R4A4_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B4G4R4A4_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2184,7 +2703,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B8G8R8A8_SRGB, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2194,13 +2713,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_SRGB: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_SRGB: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2209,7 +2728,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B8G8R8A8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2220,14 +2739,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2236,7 +2755,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_D16_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2245,12 +2764,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_D16_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2259,7 +2778,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_D32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2268,12 +2787,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_D32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2282,7 +2801,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2292,13 +2811,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2307,7 +2826,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11G11_SNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2317,13 +2836,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2332,7 +2851,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11G11_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2342,13 +2861,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2357,7 +2876,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11_SNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2367,13 +2886,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2382,7 +2901,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2392,13 +2911,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2407,7 +2926,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2417,13 +2936,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2432,7 +2951,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2442,13 +2961,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2457,7 +2976,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2467,13 +2986,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2482,7 +3001,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2492,13 +3011,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2507,7 +3026,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2517,13 +3036,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2532,7 +3051,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2542,13 +3061,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2557,7 +3076,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2568,14 +3087,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2584,7 +3103,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2595,14 +3114,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2611,7 +3130,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2620,12 +3139,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -2634,7 +3153,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2645,14 +3164,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2661,7 +3180,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2672,14 +3191,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2688,7 +3207,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2699,14 +3218,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2715,7 +3234,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2724,12 +3243,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -2738,7 +3257,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2748,13 +3267,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2763,7 +3282,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2774,14 +3293,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2790,7 +3309,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2801,14 +3320,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2817,7 +3336,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2826,12 +3345,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -2840,7 +3359,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2851,14 +3370,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2867,7 +3386,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2876,12 +3395,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -2890,7 +3409,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32B32A32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2900,13 +3419,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2915,7 +3434,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32B32A32_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2925,13 +3444,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2940,7 +3459,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32B32A32_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2950,13 +3469,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2965,7 +3484,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -2976,14 +3495,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -2992,7 +3511,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3003,14 +3522,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3019,7 +3538,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3030,14 +3549,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3046,7 +3565,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3057,14 +3576,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3073,7 +3592,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3084,14 +3603,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3100,7 +3619,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3111,14 +3630,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3127,7 +3646,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R5G6B5_UNORM_PACK16, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3137,13 +3656,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R5G6B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R5G6B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3152,7 +3671,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3163,14 +3682,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3179,7 +3698,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3190,14 +3709,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3206,7 +3725,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_SRGB, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3216,13 +3735,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SRGB: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SRGB: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3231,7 +3750,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3242,14 +3761,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3258,7 +3777,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3269,14 +3788,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3285,7 +3804,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3296,14 +3815,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3312,7 +3831,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3323,14 +3842,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3339,7 +3858,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3350,14 +3869,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3366,7 +3885,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3377,14 +3896,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3393,7 +3912,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3404,14 +3923,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3420,7 +3939,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3431,14 +3950,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3447,7 +3966,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3458,14 +3977,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3474,7 +3993,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3485,14 +4004,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3510,8 +4029,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(nullptr)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -3519,7 +4038,8 @@ static const VpStructChainerDesc chainerDesc = { pfnCb(p, pUser); }, }; -} //namespace baseline +} // namespace baseline +} // namespace blocks } // namespace VP_ANDROID_BASELINE_2021 #endif // VP_ANDROID_baseline_2021 @@ -3565,7 +4085,7 @@ static const VkExtensionProperties deviceExtensions[] = { }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); @@ -3585,23 +4105,23 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { - VkPhysicalDeviceFeatures2KHR* prettify_VkPhysicalDeviceFeatures2KHR = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.depthBiasClamp == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fragmentStoresAndAtomics == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fullDrawIndexUint32 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.imageCubeArray == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.independentBlend == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.robustBufferAccess == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.sampleRateShading == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderSampledImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionASTC_LDR == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionETC2 == VK_TRUE"); + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.textureCompressionASTC_LDR == VK_TRUE); + ret = ret && (s->features.textureCompressionETC2 == VK_TRUE); } break; default: break; } @@ -3610,9 +4130,9 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; return ret; } @@ -3627,8 +4147,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(nullptr)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -3637,7 +4157,9 @@ static const VpStructChainerDesc chainerDesc = { }, }; +namespace blocks { namespace baseline { + static const VkExtensionProperties instanceExtensions[] = { VkExtensionProperties{ VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, 1 }, VkExtensionProperties{ VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 1 }, @@ -3664,7 +4186,7 @@ static const VkExtensionProperties deviceExtensions[] = { }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); @@ -3684,23 +4206,23 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { - VkPhysicalDeviceFeatures2KHR* prettify_VkPhysicalDeviceFeatures2KHR = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.depthBiasClamp == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fragmentStoresAndAtomics == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fullDrawIndexUint32 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.imageCubeArray == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.independentBlend == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.robustBufferAccess == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.sampleRateShading == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderSampledImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionASTC_LDR == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionETC2 == VK_TRUE"); + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.textureCompressionASTC_LDR == VK_TRUE); + ret = ret && (s->features.textureCompressionETC2 == VK_TRUE); } break; default: break; } @@ -3709,7 +4231,7 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); @@ -3797,95 +4319,95 @@ static const VpPropertyDesc propertyDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { - VkPhysicalDeviceProperties2KHR* prettify_VkPhysicalDeviceProperties2KHR = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.discreteQueuePriorities >= 2); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.discreteQueuePriorities >= 2), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.discreteQueuePriorities >= 2"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferColorSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferDepthSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferNoAttachmentsSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferNoAttachmentsSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferNoAttachmentsSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferStencilSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxBoundDescriptorSets >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxBoundDescriptorSets >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxBoundDescriptorSets >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxColorAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxColorAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxColorAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeSharedMemorySize >= 16384); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeSharedMemorySize >= 16384), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeSharedMemorySize >= 16384"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[0] >= 65535); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[0] >= 65535), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupCount[0] >= 65535"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[1] >= 65535); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[1] >= 65535), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupCount[1] >= 65535"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[2] >= 65535); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[2] >= 65535), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupCount[2] >= 65535"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupInvocations >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupInvocations >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupInvocations >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[0] >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[0] >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupSize[0] >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[1] >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[1] >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupSize[1] >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[2] >= 64); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[2] >= 64), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupSize[2] >= 64"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetInputAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetInputAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetInputAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSampledImages >= 48); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSampledImages >= 48), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetSampledImages >= 48"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSamplers >= 48); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSamplers >= 48), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetSamplers >= 48"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffers >= 24); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffers >= 24), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetStorageBuffers >= 24"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageImages >= 12); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageImages >= 12), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetStorageImages >= 12"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffers >= 36); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffers >= 36), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetUniformBuffers >= 36"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndexedIndexValue >= 4294967295); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndexedIndexValue >= 4294967295), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDrawIndexedIndexValue >= 4294967295"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndirectCount >= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndirectCount >= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDrawIndirectCount >= 1"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentCombinedOutputResources >= 8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentCombinedOutputResources >= 8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFragmentCombinedOutputResources >= 8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentInputComponents >= 64); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentInputComponents >= 64), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFragmentInputComponents >= 64"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentOutputAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentOutputAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFragmentOutputAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferHeight >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferHeight >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFramebufferHeight >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferLayers >= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferLayers >= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFramebufferLayers >= 256"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferWidth >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferWidth >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFramebufferWidth >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageArrayLayers >= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageArrayLayers >= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageArrayLayers >= 256"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension1D >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension1D >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimension1D >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension2D >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension2D >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimension2D >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension3D >= 512); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension3D >= 512), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimension3D >= 512"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimensionCube >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimensionCube >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimensionCube >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxInterpolationOffset >= 0.4375); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxInterpolationOffset >= 0.4375), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxInterpolationOffset >= 0.4375"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxMemoryAllocationCount >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxMemoryAllocationCount >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxMemoryAllocationCount >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorInputAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorInputAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorInputAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSampledImages >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSampledImages >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorSampledImages >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSamplers >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSamplers >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorSamplers >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageBuffers >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageBuffers >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorStorageBuffers >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageImages >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageImages >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorStorageImages >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorUniformBuffers >= 12); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorUniformBuffers >= 12), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorUniformBuffers >= 12"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageResources >= 44); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageResources >= 44), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageResources >= 44"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPushConstantsSize >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPushConstantsSize >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPushConstantsSize >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSampleMaskWords >= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSampleMaskWords >= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSampleMaskWords >= 1"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAllocationCount >= 4000); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAllocationCount >= 4000), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSamplerAllocationCount >= 4000"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAnisotropy >= 1.0); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAnisotropy >= 1.0), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSamplerAnisotropy >= 1.0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerLodBias >= 2.0); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerLodBias >= 2.0), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSamplerLodBias >= 2.0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxStorageBufferRange >= 134217728); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxStorageBufferRange >= 134217728), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxStorageBufferRange >= 134217728"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelBufferElements >= 65536); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelBufferElements >= 65536), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxTexelBufferElements >= 65536"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelOffset >= 7); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelOffset >= 7), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxTexelOffset >= 7"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxUniformBufferRange >= 16384); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxUniformBufferRange >= 16384), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxUniformBufferRange >= 16384"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributeOffset >= 2047); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributeOffset >= 2047), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputAttributeOffset >= 2047"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributes >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributes >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputAttributes >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindingStride >= 2048); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindingStride >= 2048), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputBindingStride >= 2048"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindings >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindings >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputBindings >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexOutputComponents >= 64); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexOutputComponents >= 64), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexOutputComponents >= 64"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[0] >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[0] >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxViewportDimensions[0] >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[1] >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[1] >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxViewportDimensions[1] >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewports >= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewports >= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxViewports >= 1"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minInterpolationOffset <= -0.5); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minInterpolationOffset <= -0.5), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minInterpolationOffset <= -0.5"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment <= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment <= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minMemoryMapAlignment <= 4096"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment <= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment <= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minStorageBufferOffsetAlignment <= 256"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment <= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment <= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minTexelBufferOffsetAlignment <= 256"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelOffset <= -8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelOffset <= -8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minTexelOffset <= -8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment <= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment <= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minUniformBufferOffsetAlignment <= 256"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.mipmapPrecisionBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.mipmapPrecisionBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.mipmapPrecisionBits >= 4"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageColorSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageDepthSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageIntegerSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageIntegerSampleCounts, (VK_SAMPLE_COUNT_1_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageIntegerSampleCounts contains (VK_SAMPLE_COUNT_1_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageStencilSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.standardSampleLocations == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.standardSampleLocations == VK_TRUE), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.standardSampleLocations == VK_TRUE"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.storageImageSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.storageImageSampleCounts, (VK_SAMPLE_COUNT_1_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.storageImageSampleCounts contains (VK_SAMPLE_COUNT_1_BIT)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelInterpolationOffsetBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelInterpolationOffsetBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.subPixelInterpolationOffsetBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelPrecisionBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelPrecisionBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.subPixelPrecisionBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subTexelPrecisionBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subTexelPrecisionBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.subTexelPrecisionBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[0] <= -8192); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[0] <= -8192), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.viewportBoundsRange[0] <= -8192"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[1] >= 8191); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[1] >= 8191), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.viewportBoundsRange[1] >= 8191"); + VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (s->properties.limits.discreteQueuePriorities >= 2); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferNoAttachmentsSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (s->properties.limits.maxBoundDescriptorSets >= 4); + ret = ret && (s->properties.limits.maxColorAttachments >= 4); + ret = ret && (s->properties.limits.maxComputeSharedMemorySize >= 16384); + ret = ret && (s->properties.limits.maxComputeWorkGroupCount[0] >= 65535); + ret = ret && (s->properties.limits.maxComputeWorkGroupCount[1] >= 65535); + ret = ret && (s->properties.limits.maxComputeWorkGroupCount[2] >= 65535); + ret = ret && (s->properties.limits.maxComputeWorkGroupInvocations >= 128); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[0] >= 128); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[1] >= 128); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[2] >= 64); + ret = ret && (s->properties.limits.maxDescriptorSetInputAttachments >= 4); + ret = ret && (s->properties.limits.maxDescriptorSetSampledImages >= 48); + ret = ret && (s->properties.limits.maxDescriptorSetSamplers >= 48); + ret = ret && (s->properties.limits.maxDescriptorSetStorageBuffers >= 24); + ret = ret && (s->properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4); + ret = ret && (s->properties.limits.maxDescriptorSetStorageImages >= 12); + ret = ret && (s->properties.limits.maxDescriptorSetUniformBuffers >= 36); + ret = ret && (s->properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8); + ret = ret && (s->properties.limits.maxDrawIndexedIndexValue >= 4294967295); + ret = ret && (s->properties.limits.maxDrawIndirectCount >= 1); + ret = ret && (s->properties.limits.maxFragmentCombinedOutputResources >= 8); + ret = ret && (s->properties.limits.maxFragmentInputComponents >= 64); + ret = ret && (s->properties.limits.maxFragmentOutputAttachments >= 4); + ret = ret && (s->properties.limits.maxFramebufferHeight >= 4096); + ret = ret && (s->properties.limits.maxFramebufferLayers >= 256); + ret = ret && (s->properties.limits.maxFramebufferWidth >= 4096); + ret = ret && (s->properties.limits.maxImageArrayLayers >= 256); + ret = ret && (s->properties.limits.maxImageDimension1D >= 4096); + ret = ret && (s->properties.limits.maxImageDimension2D >= 4096); + ret = ret && (s->properties.limits.maxImageDimension3D >= 512); + ret = ret && (s->properties.limits.maxImageDimensionCube >= 4096); + ret = ret && (s->properties.limits.maxInterpolationOffset >= 0.4375); + ret = ret && (s->properties.limits.maxMemoryAllocationCount >= 4096); + ret = ret && (s->properties.limits.maxPerStageDescriptorInputAttachments >= 4); + ret = ret && (s->properties.limits.maxPerStageDescriptorSampledImages >= 16); + ret = ret && (s->properties.limits.maxPerStageDescriptorSamplers >= 16); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageBuffers >= 4); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageImages >= 4); + ret = ret && (s->properties.limits.maxPerStageDescriptorUniformBuffers >= 12); + ret = ret && (s->properties.limits.maxPerStageResources >= 44); + ret = ret && (s->properties.limits.maxPushConstantsSize >= 128); + ret = ret && (s->properties.limits.maxSampleMaskWords >= 1); + ret = ret && (s->properties.limits.maxSamplerAllocationCount >= 4000); + ret = ret && (s->properties.limits.maxSamplerAnisotropy >= 1.0); + ret = ret && (s->properties.limits.maxSamplerLodBias >= 2.0); + ret = ret && (s->properties.limits.maxStorageBufferRange >= 134217728); + ret = ret && (s->properties.limits.maxTexelBufferElements >= 65536); + ret = ret && (s->properties.limits.maxTexelOffset >= 7); + ret = ret && (s->properties.limits.maxUniformBufferRange >= 16384); + ret = ret && (s->properties.limits.maxVertexInputAttributeOffset >= 2047); + ret = ret && (s->properties.limits.maxVertexInputAttributes >= 16); + ret = ret && (s->properties.limits.maxVertexInputBindingStride >= 2048); + ret = ret && (s->properties.limits.maxVertexInputBindings >= 16); + ret = ret && (s->properties.limits.maxVertexOutputComponents >= 64); + ret = ret && (s->properties.limits.maxViewportDimensions[0] >= 4096); + ret = ret && (s->properties.limits.maxViewportDimensions[1] >= 4096); + ret = ret && (s->properties.limits.maxViewports >= 1); + ret = ret && (s->properties.limits.minInterpolationOffset <= -0.5); + ret = ret && (s->properties.limits.minMemoryMapAlignment <= 4096); + ret = ret && ((s->properties.limits.minMemoryMapAlignment & (s->properties.limits.minMemoryMapAlignment - 1)) == 0); + ret = ret && (s->properties.limits.minStorageBufferOffsetAlignment <= 256); + ret = ret && ((s->properties.limits.minStorageBufferOffsetAlignment & (s->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0); + ret = ret && (s->properties.limits.minTexelBufferOffsetAlignment <= 256); + ret = ret && ((s->properties.limits.minTexelBufferOffsetAlignment & (s->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0); + ret = ret && (s->properties.limits.minTexelOffset <= -8); + ret = ret && (s->properties.limits.minUniformBufferOffsetAlignment <= 256); + ret = ret && ((s->properties.limits.minUniformBufferOffsetAlignment & (s->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0); + ret = ret && (s->properties.limits.mipmapPrecisionBits >= 4); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageIntegerSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (s->properties.limits.standardSampleLocations == VK_TRUE); + ret = ret && (vpCheckFlags(s->properties.limits.storageImageSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); + ret = ret && (s->properties.limits.subPixelInterpolationOffsetBits >= 4); + ret = ret && (s->properties.limits.subPixelPrecisionBits >= 4); + ret = ret && (s->properties.limits.subTexelPrecisionBits >= 4); + ret = ret && (s->properties.limits.viewportBoundsRange[0] <= -8192); + ret = ret && (s->properties.limits.viewportBoundsRange[1] >= 8191); } break; default: break; } @@ -3896,7 +4418,7 @@ static const VpPropertyDesc propertyDesc = { static const VpFormatDesc formatDesc[] = { { VK_FORMAT_A1R5G5B5_UNORM_PACK16, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3906,13 +4428,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A1R5G5B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A1R5G5B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3921,7 +4443,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A2B10G10R10_UINT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3932,14 +4454,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UINT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UINT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UINT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3948,7 +4470,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A2B10G10R10_UNORM_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3959,14 +4481,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -3975,7 +4497,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_SINT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -3986,14 +4508,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SINT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SINT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SINT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4002,7 +4524,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_SNORM_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4013,14 +4535,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SNORM_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SNORM_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SNORM_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4029,7 +4551,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_SRGB_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4039,13 +4561,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SRGB_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SRGB_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4054,7 +4576,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_UINT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4065,14 +4587,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UINT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UINT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UINT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4081,7 +4603,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_UNORM_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4092,14 +4614,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4108,7 +4630,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x10_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4118,13 +4640,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4133,7 +4655,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x10_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4143,13 +4665,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4158,7 +4680,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4168,13 +4690,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4183,7 +4705,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4193,13 +4715,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4208,7 +4730,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x6_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4218,13 +4740,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4233,7 +4755,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x6_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4243,13 +4765,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4258,7 +4780,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4268,13 +4790,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4283,7 +4805,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4293,13 +4815,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4308,7 +4830,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x10_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4318,13 +4840,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4333,7 +4855,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x10_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4343,13 +4865,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4358,7 +4880,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x12_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4368,13 +4890,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4383,7 +4905,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x12_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4393,13 +4915,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4408,7 +4930,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_4x4_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4418,13 +4940,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4433,7 +4955,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_4x4_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4443,13 +4965,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4458,7 +4980,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x4_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4468,13 +4990,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4483,7 +5005,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x4_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4493,13 +5015,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4508,7 +5030,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4518,13 +5040,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4533,7 +5055,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4543,13 +5065,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4558,7 +5080,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4568,13 +5090,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4583,7 +5105,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4593,13 +5115,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4608,7 +5130,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x6_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4618,13 +5140,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4633,7 +5155,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x6_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4643,13 +5165,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4658,7 +5180,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4668,13 +5190,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4683,7 +5205,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4693,13 +5215,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4708,7 +5230,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x6_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4718,13 +5240,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4733,7 +5255,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x6_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4743,13 +5265,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4758,7 +5280,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4768,13 +5290,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4783,7 +5305,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4793,13 +5315,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4808,7 +5330,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B10G11R11_UFLOAT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4819,14 +5341,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_B10G11R11_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B10G11R11_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B10G11R11_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4835,7 +5357,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B4G4R4A4_UNORM_PACK16, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4845,13 +5367,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B4G4R4A4_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B4G4R4A4_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4860,7 +5382,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B8G8R8A8_SRGB, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4870,13 +5392,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_SRGB: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_SRGB: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4885,7 +5407,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B8G8R8A8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4896,14 +5418,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4912,7 +5434,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_D16_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4921,12 +5443,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_D16_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4935,7 +5457,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_D32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4944,12 +5466,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_D32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4958,7 +5480,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4968,13 +5490,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -4983,7 +5505,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11G11_SNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -4993,13 +5515,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5008,7 +5530,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11G11_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5018,13 +5540,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5033,7 +5555,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11_SNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5043,13 +5565,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5058,7 +5580,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5068,13 +5590,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5083,7 +5605,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5093,13 +5615,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5108,7 +5630,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5118,13 +5640,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5133,7 +5655,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5143,13 +5665,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5158,7 +5680,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5168,13 +5690,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5183,7 +5705,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5193,13 +5715,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5208,7 +5730,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5218,13 +5740,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5233,7 +5755,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5244,14 +5766,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5260,7 +5782,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5271,14 +5793,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5287,7 +5809,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5296,12 +5818,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -5310,7 +5832,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5321,14 +5843,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5337,7 +5859,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5348,14 +5870,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5364,7 +5886,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5375,14 +5897,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5391,7 +5913,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5400,12 +5922,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -5414,7 +5936,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5424,13 +5946,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5439,7 +5961,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5450,14 +5972,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5466,7 +5988,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5477,14 +5999,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5493,7 +6015,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5502,12 +6024,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -5516,7 +6038,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5527,14 +6049,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5543,7 +6065,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5552,12 +6074,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -5566,7 +6088,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32B32A32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5576,13 +6098,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5591,7 +6113,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32B32A32_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5601,13 +6123,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5616,7 +6138,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32B32A32_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5626,13 +6148,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5641,7 +6163,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5652,14 +6174,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5668,7 +6190,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5679,14 +6201,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5695,7 +6217,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5706,14 +6228,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5722,7 +6244,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5733,14 +6255,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5749,7 +6271,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5760,14 +6282,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5776,7 +6298,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5787,14 +6309,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5803,7 +6325,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R5G6B5_UNORM_PACK16, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5813,13 +6335,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R5G6B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R5G6B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5828,7 +6350,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5839,14 +6361,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5855,7 +6377,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5866,14 +6388,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5882,7 +6404,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_SRGB, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5892,13 +6414,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SRGB: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SRGB: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5907,7 +6429,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5918,14 +6440,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5934,7 +6456,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5945,14 +6467,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5961,7 +6483,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5972,14 +6494,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -5988,7 +6510,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -5999,14 +6521,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6015,7 +6537,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6026,14 +6548,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6042,7 +6564,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6053,14 +6575,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6069,7 +6591,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6080,14 +6602,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6096,7 +6618,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6107,14 +6629,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6123,7 +6645,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6134,14 +6656,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6150,7 +6672,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6161,14 +6683,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6186,8 +6708,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(nullptr)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -6195,7 +6717,8 @@ static const VpStructChainerDesc chainerDesc = { pfnCb(p, pUser); }, }; -} //namespace baseline +} // namespace baseline +} // namespace blocks } // namespace VP_ANDROID_BASELINE_2021_CPU_ONLY #endif // VP_ANDROID_baseline_2021_cpu_only @@ -6254,7 +6777,7 @@ static const VkExtensionProperties deviceExtensions[] = { }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); @@ -6294,43 +6817,43 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { - VkPhysicalDeviceFeatures2KHR* prettify_VkPhysicalDeviceFeatures2KHR = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.depthBiasClamp == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fragmentStoresAndAtomics == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fullDrawIndexUint32 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.imageCubeArray == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.independentBlend == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.largePoints == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.largePoints == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.largePoints == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.robustBufferAccess == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.sampleRateShading == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderInt16 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderInt16 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderInt16 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderSampledImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionASTC_LDR == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionETC2 == VK_TRUE"); + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.largePoints == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.shaderInt16 == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.textureCompressionASTC_LDR == VK_TRUE); + ret = ret && (s->features.textureCompressionETC2 == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: { - VkPhysicalDeviceMultiviewFeatures* prettify_VkPhysicalDeviceMultiviewFeatures = static_cast<VkPhysicalDeviceMultiviewFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceMultiviewFeatures->multiview == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceMultiviewFeatures->multiview == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceMultiviewFeatures::multiview == VK_TRUE"); + VkPhysicalDeviceMultiviewFeatures* s = static_cast<VkPhysicalDeviceMultiviewFeatures*>(static_cast<void*>(p)); + ret = ret && (s->multiview == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: { - VkPhysicalDeviceSamplerYcbcrConversionFeatures* prettify_VkPhysicalDeviceSamplerYcbcrConversionFeatures = static_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceSamplerYcbcrConversionFeatures->samplerYcbcrConversion == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceSamplerYcbcrConversionFeatures->samplerYcbcrConversion == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceSamplerYcbcrConversionFeatures::samplerYcbcrConversion == VK_TRUE"); + VkPhysicalDeviceSamplerYcbcrConversionFeatures* s = static_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(static_cast<void*>(p)); + ret = ret && (s->samplerYcbcrConversion == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: { - VkPhysicalDeviceShaderDrawParametersFeatures* prettify_VkPhysicalDeviceShaderDrawParametersFeatures = static_cast<VkPhysicalDeviceShaderDrawParametersFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceShaderDrawParametersFeatures->shaderDrawParameters == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceShaderDrawParametersFeatures->shaderDrawParameters == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceShaderDrawParametersFeatures::shaderDrawParameters == VK_TRUE"); + VkPhysicalDeviceShaderDrawParametersFeatures* s = static_cast<VkPhysicalDeviceShaderDrawParametersFeatures*>(static_cast<void*>(p)); + ret = ret && (s->shaderDrawParameters == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: { - VkPhysicalDeviceVariablePointersFeatures* prettify_VkPhysicalDeviceVariablePointersFeatures = static_cast<VkPhysicalDeviceVariablePointersFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceVariablePointersFeatures->variablePointers == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceVariablePointersFeatures->variablePointers == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceVariablePointersFeatures::variablePointers == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceVariablePointersFeatures->variablePointersStorageBuffer == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceVariablePointersFeatures->variablePointersStorageBuffer == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceVariablePointersFeatures::variablePointersStorageBuffer == VK_TRUE"); + VkPhysicalDeviceVariablePointersFeatures* s = static_cast<VkPhysicalDeviceVariablePointersFeatures*>(static_cast<void*>(p)); + ret = ret && (s->variablePointers == VK_TRUE); + ret = ret && (s->variablePointersStorageBuffer == VK_TRUE); } break; default: break; } @@ -6339,9 +6862,9 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; return ret; } @@ -6361,8 +6884,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceMultiviewProperties)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -6371,7 +6894,9 @@ static const VpStructChainerDesc chainerDesc = { }, }; +namespace blocks { namespace baseline { + static const VkExtensionProperties instanceExtensions[] = { VkExtensionProperties{ VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, 1 }, VkExtensionProperties{ VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 1 }, @@ -6406,7 +6931,7 @@ static const VkExtensionProperties deviceExtensions[] = { }; static const VpFeatureDesc featureDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); @@ -6446,43 +6971,43 @@ static const VpFeatureDesc featureDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { - VkPhysicalDeviceFeatures2KHR* prettify_VkPhysicalDeviceFeatures2KHR = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.depthBiasClamp == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.depthBiasClamp == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fragmentStoresAndAtomics == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fragmentStoresAndAtomics == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.fullDrawIndexUint32 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.fullDrawIndexUint32 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.imageCubeArray == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.imageCubeArray == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.independentBlend == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.independentBlend == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.largePoints == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.largePoints == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.largePoints == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.robustBufferAccess == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.robustBufferAccess == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.sampleRateShading == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.sampleRateShading == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderInt16 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderInt16 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderInt16 == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderSampledImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderStorageImageArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionASTC_LDR == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionASTC_LDR == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceFeatures2KHR->features.textureCompressionETC2 == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceFeatures2KHR::features.textureCompressionETC2 == VK_TRUE"); + VkPhysicalDeviceFeatures2KHR* s = static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.largePoints == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.shaderInt16 == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.textureCompressionASTC_LDR == VK_TRUE); + ret = ret && (s->features.textureCompressionETC2 == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: { - VkPhysicalDeviceMultiviewFeatures* prettify_VkPhysicalDeviceMultiviewFeatures = static_cast<VkPhysicalDeviceMultiviewFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceMultiviewFeatures->multiview == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceMultiviewFeatures->multiview == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceMultiviewFeatures::multiview == VK_TRUE"); + VkPhysicalDeviceMultiviewFeatures* s = static_cast<VkPhysicalDeviceMultiviewFeatures*>(static_cast<void*>(p)); + ret = ret && (s->multiview == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: { - VkPhysicalDeviceSamplerYcbcrConversionFeatures* prettify_VkPhysicalDeviceSamplerYcbcrConversionFeatures = static_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceSamplerYcbcrConversionFeatures->samplerYcbcrConversion == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceSamplerYcbcrConversionFeatures->samplerYcbcrConversion == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceSamplerYcbcrConversionFeatures::samplerYcbcrConversion == VK_TRUE"); + VkPhysicalDeviceSamplerYcbcrConversionFeatures* s = static_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures*>(static_cast<void*>(p)); + ret = ret && (s->samplerYcbcrConversion == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: { - VkPhysicalDeviceShaderDrawParametersFeatures* prettify_VkPhysicalDeviceShaderDrawParametersFeatures = static_cast<VkPhysicalDeviceShaderDrawParametersFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceShaderDrawParametersFeatures->shaderDrawParameters == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceShaderDrawParametersFeatures->shaderDrawParameters == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceShaderDrawParametersFeatures::shaderDrawParameters == VK_TRUE"); + VkPhysicalDeviceShaderDrawParametersFeatures* s = static_cast<VkPhysicalDeviceShaderDrawParametersFeatures*>(static_cast<void*>(p)); + ret = ret && (s->shaderDrawParameters == VK_TRUE); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: { - VkPhysicalDeviceVariablePointersFeatures* prettify_VkPhysicalDeviceVariablePointersFeatures = static_cast<VkPhysicalDeviceVariablePointersFeatures*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceVariablePointersFeatures->variablePointers == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceVariablePointersFeatures->variablePointers == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceVariablePointersFeatures::variablePointers == VK_TRUE"); - ret = ret && (prettify_VkPhysicalDeviceVariablePointersFeatures->variablePointersStorageBuffer == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceVariablePointersFeatures->variablePointersStorageBuffer == VK_TRUE), "Unsupported feature condition: VkPhysicalDeviceVariablePointersFeatures::variablePointersStorageBuffer == VK_TRUE"); + VkPhysicalDeviceVariablePointersFeatures* s = static_cast<VkPhysicalDeviceVariablePointersFeatures*>(static_cast<void*>(p)); + ret = ret && (s->variablePointers == VK_TRUE); + ret = ret && (s->variablePointersStorageBuffer == VK_TRUE); } break; default: break; } @@ -6491,7 +7016,7 @@ static const VpFeatureDesc featureDesc = { }; static const VpPropertyDesc propertyDesc = { - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); @@ -6587,104 +7112,104 @@ static const VpPropertyDesc propertyDesc = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { - VkPhysicalDeviceProperties2KHR* prettify_VkPhysicalDeviceProperties2KHR = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.discreteQueuePriorities >= 2); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.discreteQueuePriorities >= 2), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.discreteQueuePriorities >= 2"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferColorSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferDepthSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferNoAttachmentsSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferNoAttachmentsSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferNoAttachmentsSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.framebufferStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.framebufferStencilSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxBoundDescriptorSets >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxBoundDescriptorSets >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxBoundDescriptorSets >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxColorAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxColorAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxColorAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeSharedMemorySize >= 16384); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeSharedMemorySize >= 16384), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeSharedMemorySize >= 16384"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[0] >= 65535); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[0] >= 65535), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupCount[0] >= 65535"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[1] >= 65535); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[1] >= 65535), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupCount[1] >= 65535"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[2] >= 65535); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupCount[2] >= 65535), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupCount[2] >= 65535"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupInvocations >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupInvocations >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupInvocations >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[0] >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[0] >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupSize[0] >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[1] >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[1] >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupSize[1] >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[2] >= 64); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxComputeWorkGroupSize[2] >= 64), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxComputeWorkGroupSize[2] >= 64"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetInputAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetInputAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetInputAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSampledImages >= 48); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSampledImages >= 48), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetSampledImages >= 48"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSamplers >= 48); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetSamplers >= 48), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetSamplers >= 48"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffers >= 24); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffers >= 24), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetStorageBuffers >= 24"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageImages >= 12); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetStorageImages >= 12), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetStorageImages >= 12"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffers >= 36); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffers >= 36), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetUniformBuffers >= 36"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndexedIndexValue >= 4294967295); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndexedIndexValue >= 4294967295), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDrawIndexedIndexValue >= 4294967295"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndirectCount >= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxDrawIndirectCount >= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxDrawIndirectCount >= 1"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentCombinedOutputResources >= 8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentCombinedOutputResources >= 8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFragmentCombinedOutputResources >= 8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentInputComponents >= 64); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentInputComponents >= 64), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFragmentInputComponents >= 64"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentOutputAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFragmentOutputAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFragmentOutputAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferHeight >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferHeight >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFramebufferHeight >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferLayers >= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferLayers >= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFramebufferLayers >= 256"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferWidth >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxFramebufferWidth >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxFramebufferWidth >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageArrayLayers >= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageArrayLayers >= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageArrayLayers >= 256"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension1D >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension1D >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimension1D >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension2D >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension2D >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimension2D >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension3D >= 512); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimension3D >= 512), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimension3D >= 512"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimensionCube >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxImageDimensionCube >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxImageDimensionCube >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxInterpolationOffset >= 0.4375); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxInterpolationOffset >= 0.4375), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxInterpolationOffset >= 0.4375"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxMemoryAllocationCount >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxMemoryAllocationCount >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxMemoryAllocationCount >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorInputAttachments >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorInputAttachments >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorInputAttachments >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSampledImages >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSampledImages >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorSampledImages >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSamplers >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorSamplers >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorSamplers >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageBuffers >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageBuffers >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorStorageBuffers >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageImages >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorStorageImages >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorStorageImages >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorUniformBuffers >= 12); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageDescriptorUniformBuffers >= 12), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageDescriptorUniformBuffers >= 12"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageResources >= 44); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPerStageResources >= 44), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPerStageResources >= 44"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPushConstantsSize >= 128); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxPushConstantsSize >= 128), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxPushConstantsSize >= 128"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSampleMaskWords >= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSampleMaskWords >= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSampleMaskWords >= 1"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAllocationCount >= 4000); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAllocationCount >= 4000), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSamplerAllocationCount >= 4000"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAnisotropy >= 1.0); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerAnisotropy >= 1.0), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSamplerAnisotropy >= 1.0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerLodBias >= 2.0); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxSamplerLodBias >= 2.0), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxSamplerLodBias >= 2.0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxStorageBufferRange >= 134217728); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxStorageBufferRange >= 134217728), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxStorageBufferRange >= 134217728"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelBufferElements >= 65536); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelBufferElements >= 65536), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxTexelBufferElements >= 65536"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelOffset >= 7); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxTexelOffset >= 7), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxTexelOffset >= 7"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxUniformBufferRange >= 16384); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxUniformBufferRange >= 16384), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxUniformBufferRange >= 16384"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributeOffset >= 2047); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributeOffset >= 2047), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputAttributeOffset >= 2047"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributes >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputAttributes >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputAttributes >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindingStride >= 2048); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindingStride >= 2048), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputBindingStride >= 2048"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindings >= 16); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexInputBindings >= 16), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexInputBindings >= 16"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexOutputComponents >= 64); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxVertexOutputComponents >= 64), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxVertexOutputComponents >= 64"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[0] >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[0] >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxViewportDimensions[0] >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[1] >= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewportDimensions[1] >= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxViewportDimensions[1] >= 4096"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewports >= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.maxViewports >= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.maxViewports >= 1"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minInterpolationOffset <= -0.5); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minInterpolationOffset <= -0.5), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minInterpolationOffset <= -0.5"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment <= 4096); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment <= 4096), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minMemoryMapAlignment <= 4096"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minMemoryMapAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment <= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment <= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minStorageBufferOffsetAlignment <= 256"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment <= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment <= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minTexelBufferOffsetAlignment <= 256"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelOffset <= -8); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minTexelOffset <= -8), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minTexelOffset <= -8"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment <= 256); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment <= 256), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.minUniformBufferOffsetAlignment <= 256"); - ret = ret && ((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0); VP_DEBUG_COND_MSG(!((prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0), "Unsupported properties condition: (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment & (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.mipmapPrecisionBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.mipmapPrecisionBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.mipmapPrecisionBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity <= 1); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity <= 1), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.pointSizeGranularity <= 1"); - ret = ret && (isMultiple(1, prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity)); VP_DEBUG_COND_MSG(!(isMultiple(1, prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity)), "Unsupported properties condition: isMultiple(1, prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeGranularity)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeRange[0] <= 1.0); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeRange[0] <= 1.0), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.pointSizeRange[0] <= 1.0"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeRange[1] >= 511); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.pointSizeRange[1] >= 511), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.pointSizeRange[1] >= 511"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageColorSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageDepthSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageIntegerSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageIntegerSampleCounts, (VK_SAMPLE_COUNT_1_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageIntegerSampleCounts contains (VK_SAMPLE_COUNT_1_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.sampledImageStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.sampledImageStencilSampleCounts contains (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.standardSampleLocations == VK_TRUE); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.standardSampleLocations == VK_TRUE), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.standardSampleLocations == VK_TRUE"); - ret = ret && (vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.storageImageSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.storageImageSampleCounts, (VK_SAMPLE_COUNT_1_BIT))), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.storageImageSampleCounts contains (VK_SAMPLE_COUNT_1_BIT)"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelInterpolationOffsetBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelInterpolationOffsetBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.subPixelInterpolationOffsetBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelPrecisionBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subPixelPrecisionBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.subPixelPrecisionBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subTexelPrecisionBits >= 4); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.subTexelPrecisionBits >= 4), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.subTexelPrecisionBits >= 4"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[0] <= -8192); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[0] <= -8192), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.viewportBoundsRange[0] <= -8192"); - ret = ret && (prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[1] >= 8191); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceProperties2KHR->properties.limits.viewportBoundsRange[1] >= 8191), "Unsupported properties condition: VkPhysicalDeviceProperties2KHR::properties.limits.viewportBoundsRange[1] >= 8191"); + VkPhysicalDeviceProperties2KHR* s = static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (s->properties.limits.discreteQueuePriorities >= 2); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferNoAttachmentsSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.framebufferStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (s->properties.limits.maxBoundDescriptorSets >= 4); + ret = ret && (s->properties.limits.maxColorAttachments >= 4); + ret = ret && (s->properties.limits.maxComputeSharedMemorySize >= 16384); + ret = ret && (s->properties.limits.maxComputeWorkGroupCount[0] >= 65535); + ret = ret && (s->properties.limits.maxComputeWorkGroupCount[1] >= 65535); + ret = ret && (s->properties.limits.maxComputeWorkGroupCount[2] >= 65535); + ret = ret && (s->properties.limits.maxComputeWorkGroupInvocations >= 128); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[0] >= 128); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[1] >= 128); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[2] >= 64); + ret = ret && (s->properties.limits.maxDescriptorSetInputAttachments >= 4); + ret = ret && (s->properties.limits.maxDescriptorSetSampledImages >= 48); + ret = ret && (s->properties.limits.maxDescriptorSetSamplers >= 48); + ret = ret && (s->properties.limits.maxDescriptorSetStorageBuffers >= 24); + ret = ret && (s->properties.limits.maxDescriptorSetStorageBuffersDynamic >= 4); + ret = ret && (s->properties.limits.maxDescriptorSetStorageImages >= 12); + ret = ret && (s->properties.limits.maxDescriptorSetUniformBuffers >= 36); + ret = ret && (s->properties.limits.maxDescriptorSetUniformBuffersDynamic >= 8); + ret = ret && (s->properties.limits.maxDrawIndexedIndexValue >= 4294967295); + ret = ret && (s->properties.limits.maxDrawIndirectCount >= 1); + ret = ret && (s->properties.limits.maxFragmentCombinedOutputResources >= 8); + ret = ret && (s->properties.limits.maxFragmentInputComponents >= 64); + ret = ret && (s->properties.limits.maxFragmentOutputAttachments >= 4); + ret = ret && (s->properties.limits.maxFramebufferHeight >= 4096); + ret = ret && (s->properties.limits.maxFramebufferLayers >= 256); + ret = ret && (s->properties.limits.maxFramebufferWidth >= 4096); + ret = ret && (s->properties.limits.maxImageArrayLayers >= 256); + ret = ret && (s->properties.limits.maxImageDimension1D >= 4096); + ret = ret && (s->properties.limits.maxImageDimension2D >= 4096); + ret = ret && (s->properties.limits.maxImageDimension3D >= 512); + ret = ret && (s->properties.limits.maxImageDimensionCube >= 4096); + ret = ret && (s->properties.limits.maxInterpolationOffset >= 0.4375); + ret = ret && (s->properties.limits.maxMemoryAllocationCount >= 4096); + ret = ret && (s->properties.limits.maxPerStageDescriptorInputAttachments >= 4); + ret = ret && (s->properties.limits.maxPerStageDescriptorSampledImages >= 16); + ret = ret && (s->properties.limits.maxPerStageDescriptorSamplers >= 16); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageBuffers >= 4); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageImages >= 4); + ret = ret && (s->properties.limits.maxPerStageDescriptorUniformBuffers >= 12); + ret = ret && (s->properties.limits.maxPerStageResources >= 44); + ret = ret && (s->properties.limits.maxPushConstantsSize >= 128); + ret = ret && (s->properties.limits.maxSampleMaskWords >= 1); + ret = ret && (s->properties.limits.maxSamplerAllocationCount >= 4000); + ret = ret && (s->properties.limits.maxSamplerAnisotropy >= 1.0); + ret = ret && (s->properties.limits.maxSamplerLodBias >= 2.0); + ret = ret && (s->properties.limits.maxStorageBufferRange >= 134217728); + ret = ret && (s->properties.limits.maxTexelBufferElements >= 65536); + ret = ret && (s->properties.limits.maxTexelOffset >= 7); + ret = ret && (s->properties.limits.maxUniformBufferRange >= 16384); + ret = ret && (s->properties.limits.maxVertexInputAttributeOffset >= 2047); + ret = ret && (s->properties.limits.maxVertexInputAttributes >= 16); + ret = ret && (s->properties.limits.maxVertexInputBindingStride >= 2048); + ret = ret && (s->properties.limits.maxVertexInputBindings >= 16); + ret = ret && (s->properties.limits.maxVertexOutputComponents >= 64); + ret = ret && (s->properties.limits.maxViewportDimensions[0] >= 4096); + ret = ret && (s->properties.limits.maxViewportDimensions[1] >= 4096); + ret = ret && (s->properties.limits.maxViewports >= 1); + ret = ret && (s->properties.limits.minInterpolationOffset <= -0.5); + ret = ret && (s->properties.limits.minMemoryMapAlignment <= 4096); + ret = ret && ((s->properties.limits.minMemoryMapAlignment & (s->properties.limits.minMemoryMapAlignment - 1)) == 0); + ret = ret && (s->properties.limits.minStorageBufferOffsetAlignment <= 256); + ret = ret && ((s->properties.limits.minStorageBufferOffsetAlignment & (s->properties.limits.minStorageBufferOffsetAlignment - 1)) == 0); + ret = ret && (s->properties.limits.minTexelBufferOffsetAlignment <= 256); + ret = ret && ((s->properties.limits.minTexelBufferOffsetAlignment & (s->properties.limits.minTexelBufferOffsetAlignment - 1)) == 0); + ret = ret && (s->properties.limits.minTexelOffset <= -8); + ret = ret && (s->properties.limits.minUniformBufferOffsetAlignment <= 256); + ret = ret && ((s->properties.limits.minUniformBufferOffsetAlignment & (s->properties.limits.minUniformBufferOffsetAlignment - 1)) == 0); + ret = ret && (s->properties.limits.mipmapPrecisionBits >= 4); + ret = ret && (s->properties.limits.pointSizeGranularity <= 1); + ret = ret && (isMultiple(1, s->properties.limits.pointSizeGranularity)); + ret = ret && (s->properties.limits.pointSizeRange[0] <= 1.0); + ret = ret && (s->properties.limits.pointSizeRange[1] >= 511); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageColorSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageDepthSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageIntegerSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); + ret = ret && (vpCheckFlags(s->properties.limits.sampledImageStencilSampleCounts, (VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT))); + ret = ret && (s->properties.limits.standardSampleLocations == VK_TRUE); + ret = ret && (vpCheckFlags(s->properties.limits.storageImageSampleCounts, (VK_SAMPLE_COUNT_1_BIT))); + ret = ret && (s->properties.limits.subPixelInterpolationOffsetBits >= 4); + ret = ret && (s->properties.limits.subPixelPrecisionBits >= 4); + ret = ret && (s->properties.limits.subTexelPrecisionBits >= 4); + ret = ret && (s->properties.limits.viewportBoundsRange[0] <= -8192); + ret = ret && (s->properties.limits.viewportBoundsRange[1] >= 8191); } break; case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: { - VkPhysicalDeviceMultiviewProperties* prettify_VkPhysicalDeviceMultiviewProperties = static_cast<VkPhysicalDeviceMultiviewProperties*>(static_cast<void*>(p)); - ret = ret && (prettify_VkPhysicalDeviceMultiviewProperties->maxMultiviewInstanceIndex >= 134217727); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceMultiviewProperties->maxMultiviewInstanceIndex >= 134217727), "Unsupported properties condition: VkPhysicalDeviceMultiviewProperties::maxMultiviewInstanceIndex >= 134217727"); - ret = ret && (prettify_VkPhysicalDeviceMultiviewProperties->maxMultiviewViewCount >= 6); VP_DEBUG_COND_MSG(!(prettify_VkPhysicalDeviceMultiviewProperties->maxMultiviewViewCount >= 6), "Unsupported properties condition: VkPhysicalDeviceMultiviewProperties::maxMultiviewViewCount >= 6"); + VkPhysicalDeviceMultiviewProperties* s = static_cast<VkPhysicalDeviceMultiviewProperties*>(static_cast<void*>(p)); + ret = ret && (s->maxMultiviewInstanceIndex >= 134217727); + ret = ret && (s->maxMultiviewViewCount >= 6); } break; default: break; } @@ -6695,7 +7220,7 @@ static const VpPropertyDesc propertyDesc = { static const VpFormatDesc formatDesc[] = { { VK_FORMAT_A1R5G5B5_UNORM_PACK16, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6705,13 +7230,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A1R5G5B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A1R5G5B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6720,7 +7245,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A2B10G10R10_UINT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6731,14 +7256,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UINT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UINT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UINT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6747,7 +7272,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A2B10G10R10_UNORM_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6758,14 +7283,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A2B10G10R10_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6774,7 +7299,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_SINT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6785,14 +7310,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SINT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SINT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SINT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6801,7 +7326,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_SNORM_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6812,14 +7337,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SNORM_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SNORM_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SNORM_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6828,7 +7353,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_SRGB_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6838,13 +7363,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SRGB_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_SRGB_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6853,7 +7378,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_UINT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6864,14 +7389,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UINT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UINT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UINT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6880,7 +7405,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_A8B8G8R8_UNORM_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6891,14 +7416,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_A8B8G8R8_UNORM_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6907,7 +7432,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x10_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6917,13 +7442,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6932,7 +7457,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x10_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6942,13 +7467,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6957,7 +7482,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6967,13 +7492,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -6982,7 +7507,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -6992,13 +7517,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7007,7 +7532,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x6_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7017,13 +7542,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7032,7 +7557,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x6_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7042,13 +7567,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7057,7 +7582,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7067,13 +7592,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7082,7 +7607,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_10x8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7092,13 +7617,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_10x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7107,7 +7632,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x10_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7117,13 +7642,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7132,7 +7657,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x10_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7142,13 +7667,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x10_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7157,7 +7682,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x12_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7167,13 +7692,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7182,7 +7707,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_12x12_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7192,13 +7717,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_12x12_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7207,7 +7732,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_4x4_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7217,13 +7742,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7232,7 +7757,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_4x4_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7242,13 +7767,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_4x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7257,7 +7782,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x4_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7267,13 +7792,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7282,7 +7807,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x4_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7292,13 +7817,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x4_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7307,7 +7832,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7317,13 +7842,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7332,7 +7857,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_5x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7342,13 +7867,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_5x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7357,7 +7882,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7367,13 +7892,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7382,7 +7907,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7392,13 +7917,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7407,7 +7932,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x6_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7417,13 +7942,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7432,7 +7957,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_6x6_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7442,13 +7967,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_6x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7457,7 +7982,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x5_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7467,13 +7992,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7482,7 +8007,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x5_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7492,13 +8017,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x5_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7507,7 +8032,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x6_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7517,13 +8042,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7532,7 +8057,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x6_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7542,13 +8067,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x6_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7557,7 +8082,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7567,13 +8092,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7582,7 +8107,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ASTC_8x8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7592,13 +8117,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ASTC_8x8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7607,7 +8132,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B10G11R11_UFLOAT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7618,14 +8143,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_B10G11R11_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B10G11R11_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B10G11R11_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7634,7 +8159,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B4G4R4A4_UNORM_PACK16, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7644,13 +8169,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B4G4R4A4_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B4G4R4A4_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7659,7 +8184,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B8G8R8A8_SRGB, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7669,13 +8194,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_SRGB: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_SRGB: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7684,7 +8209,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_B8G8R8A8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7695,14 +8220,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_B8G8R8A8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7711,7 +8236,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_D16_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7720,12 +8245,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_D16_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7734,7 +8259,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_D32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7743,12 +8268,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_D32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7757,7 +8282,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7767,13 +8292,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7782,7 +8307,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11G11_SNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7792,13 +8317,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7807,7 +8332,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11G11_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7817,13 +8342,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11G11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7832,7 +8357,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11_SNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7842,13 +8367,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_SNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7857,7 +8382,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_EAC_R11_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7867,13 +8392,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_EAC_R11_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7882,7 +8407,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7892,13 +8417,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7907,7 +8432,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7917,13 +8442,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7932,7 +8457,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7942,13 +8467,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7957,7 +8482,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7967,13 +8492,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -7982,7 +8507,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -7992,13 +8517,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8007,7 +8532,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8017,13 +8542,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8032,7 +8557,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8043,14 +8568,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8059,7 +8584,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8070,14 +8595,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8086,7 +8611,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8095,12 +8620,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -8109,7 +8634,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16B16A16_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8120,14 +8645,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16B16A16_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8136,7 +8661,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8147,14 +8672,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8163,7 +8688,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8174,14 +8699,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8190,7 +8715,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8199,12 +8724,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -8213,7 +8738,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16G16_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8223,13 +8748,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16G16_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8238,7 +8763,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8249,14 +8774,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8265,7 +8790,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8276,14 +8801,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8292,7 +8817,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8301,12 +8826,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -8315,7 +8840,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8326,14 +8851,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R16_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8342,7 +8867,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R16_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8351,12 +8876,12 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R16_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); } break; default: break; } @@ -8365,7 +8890,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32B32A32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8375,13 +8900,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8390,7 +8915,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32B32A32_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8400,13 +8925,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8415,7 +8940,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32B32A32_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8425,13 +8950,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32B32A32_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8440,7 +8965,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8451,14 +8976,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8467,7 +8992,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8478,14 +9003,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8494,7 +9019,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32G32_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8505,14 +9030,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32G32_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8521,7 +9046,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32_SFLOAT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8532,14 +9057,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32_SFLOAT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SFLOAT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SFLOAT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8548,7 +9073,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8559,14 +9084,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8575,7 +9100,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R32_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8586,14 +9111,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R32_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R32_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8602,7 +9127,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R5G6B5_UNORM_PACK16, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8612,13 +9137,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R5G6B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R5G6B5_UNORM_PACK16: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8627,7 +9152,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8638,14 +9163,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8654,7 +9179,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8665,14 +9190,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8681,7 +9206,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_SRGB, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8691,13 +9216,13 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SRGB: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_SRGB: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8706,7 +9231,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8717,14 +9242,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8733,7 +9258,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8B8A8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8744,14 +9269,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8B8A8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8760,7 +9285,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8771,14 +9296,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8787,7 +9312,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8798,14 +9323,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_SNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8814,7 +9339,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8825,14 +9350,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8841,7 +9366,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8G8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8852,14 +9377,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8G8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8868,7 +9393,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_SINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8879,14 +9404,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_SINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8895,7 +9420,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_SNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8906,14 +9431,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_SNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_SNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8922,7 +9447,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_UINT, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8933,14 +9458,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_UINT: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UINT: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UINT: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8949,7 +9474,7 @@ static const VpFormatDesc formatDesc[] = { }, { VK_FORMAT_R8_UNORM, - [](VkBaseOutStructure* p) { + [](VkBaseOutStructure* p) { (void)p; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); @@ -8960,14 +9485,14 @@ static const VpFormatDesc formatDesc[] = { default: break; } }, - [](VkBaseOutStructure* p) -> bool { + [](VkBaseOutStructure* p) -> bool { (void)p; bool ret = true; switch (p->sType) { case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR: { - VkFormatProperties2KHR* prettify_VkFormatProperties2KHR = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))), "Unsupported format condition for VK_FORMAT_R8_UNORM: VkFormatProperties2KHR::formatProperties.bufferFeatures contains (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UNORM: VkFormatProperties2KHR::formatProperties.linearTilingFeatures contains (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); - ret = ret && (vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); VP_DEBUG_COND_MSG(!(vpCheckFlags(prettify_VkFormatProperties2KHR->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))), "Unsupported format condition for VK_FORMAT_R8_UNORM: VkFormatProperties2KHR::formatProperties.optimalTilingFeatures contains (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)"); + VkFormatProperties2KHR* s = static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p)); + ret = ret && (vpCheckFlags(s->formatProperties.bufferFeatures, (VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.linearTilingFeatures, (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); + ret = ret && (vpCheckFlags(s->formatProperties.optimalTilingFeatures, (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))); } break; default: break; } @@ -8990,8 +9515,8 @@ static const VpStructChainerDesc chainerDesc = { p->pNext = static_cast<VkBaseOutStructure*>(static_cast<void*>(&physicalDeviceMultiviewProperties)); pfnCb(p, pUser); }, - [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { - pfnCb(p, pUser); + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); }, [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { VkFormatProperties3KHR formatProperties3KHR{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR, nullptr }; @@ -8999,105 +9524,113 @@ static const VpStructChainerDesc chainerDesc = { pfnCb(p, pUser); }, }; -} //namespace baseline +} // namespace baseline +} // namespace blocks } // namespace VP_ANDROID_BASELINE_2022 #endif // VP_ANDROID_baseline_2022 #ifdef VP_ANDROID_15_minimums namespace VP_ANDROID_15_MINIMUMS { - namespace MUST { - static const VpVariantDesc variants[] = { - { - "MUST", - static_cast<uint32_t>(std::size(MUST::instanceExtensions)), MUST::instanceExtensions, - static_cast<uint32_t>(std::size(MUST::deviceExtensions)), MUST::deviceExtensions, - static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, - MUST::featureDesc, - static_cast<uint32_t>(std::size(propertyStructTypes)), propertyStructTypes, - MUST::propertyDesc, - 0, nullptr, - 0, nullptr, - static_cast<uint32_t>(std::size(formatStructTypes)), formatStructTypes, - static_cast<uint32_t>(std::size(MUST::formatDesc)), MUST::formatDesc, - MUST::chainerDesc, - }, - }; - static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); - } // namespace MUST - - namespace primitivesGeneratedQuery_pipelineStatisticsQuery_ { - static const VpVariantDesc variants[] = { - { - "primitivesGeneratedQuery", - 0, nullptr, - static_cast<uint32_t>(std::size(primitivesGeneratedQuery::deviceExtensions)), primitivesGeneratedQuery::deviceExtensions, - static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, - primitivesGeneratedQuery::featureDesc, - 0, nullptr, - primitivesGeneratedQuery::propertyDesc, - 0, nullptr, - 0, nullptr, - 0, nullptr, - 0, nullptr, - primitivesGeneratedQuery::chainerDesc, - }, - { - "pipelineStatisticsQuery", - 0, nullptr, - 0, nullptr, - static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, - pipelineStatisticsQuery::featureDesc, - 0, nullptr, - pipelineStatisticsQuery::propertyDesc, - 0, nullptr, - 0, nullptr, - 0, nullptr, - 0, nullptr, - pipelineStatisticsQuery::chainerDesc, - }, - }; - static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); - } // namespace primitivesGeneratedQuery_pipelineStatisticsQuery_ - - namespace swBresenhamLines_hwBresenhamLines_ { - static const VpVariantDesc variants[] = { - { - "swBresenhamLines", - 0, nullptr, - static_cast<uint32_t>(std::size(swBresenhamLines::deviceExtensions)), swBresenhamLines::deviceExtensions, - static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, - swBresenhamLines::featureDesc, - 0, nullptr, - swBresenhamLines::propertyDesc, - 0, nullptr, - 0, nullptr, - 0, nullptr, - 0, nullptr, - swBresenhamLines::chainerDesc, - }, - { - "hwBresenhamLines", - 0, nullptr, - static_cast<uint32_t>(std::size(hwBresenhamLines::deviceExtensions)), hwBresenhamLines::deviceExtensions, - static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, - hwBresenhamLines::featureDesc, - 0, nullptr, - hwBresenhamLines::propertyDesc, - 0, nullptr, - 0, nullptr, - 0, nullptr, - 0, nullptr, - hwBresenhamLines::chainerDesc, - }, - }; - static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); - } // namespace swBresenhamLines_hwBresenhamLines_ + namespace blocks { + namespace MUST { + static const VpVariantDesc variants[] = { + { + "MUST", + static_cast<uint32_t>(std::size(blocks::MUST::instanceExtensions)), blocks::MUST::instanceExtensions, + static_cast<uint32_t>(std::size(blocks::MUST::deviceExtensions)), blocks::MUST::deviceExtensions, + static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, + blocks::MUST::featureDesc, + static_cast<uint32_t>(std::size(propertyStructTypes)), propertyStructTypes, + blocks::MUST::propertyDesc, + 0, nullptr, + 0, nullptr, + static_cast<uint32_t>(std::size(formatStructTypes)), formatStructTypes, + static_cast<uint32_t>(std::size(blocks::MUST::formatDesc)), blocks::MUST::formatDesc, + blocks::MUST::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); + } // namespace MUST + + namespace primitivesGeneratedQuery_pipelineStatisticsQuery_ { + static const VpVariantDesc variants[] = { + { + "primitivesGeneratedQuery", + 0, nullptr, + static_cast<uint32_t>(std::size(blocks::primitivesGeneratedQuery::deviceExtensions)), blocks::primitivesGeneratedQuery::deviceExtensions, + static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, + blocks::primitivesGeneratedQuery::featureDesc, + 0, nullptr, + blocks::primitivesGeneratedQuery::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::primitivesGeneratedQuery::chainerDesc, + 0, nullptr, + }, + { + "pipelineStatisticsQuery", + 0, nullptr, + 0, nullptr, + static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, + blocks::pipelineStatisticsQuery::featureDesc, + 0, nullptr, + blocks::pipelineStatisticsQuery::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::pipelineStatisticsQuery::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); + } // namespace primitivesGeneratedQuery_pipelineStatisticsQuery_ + + namespace swBresenhamLines_hwBresenhamLines_ { + static const VpVariantDesc variants[] = { + { + "swBresenhamLines", + 0, nullptr, + static_cast<uint32_t>(std::size(blocks::swBresenhamLines::deviceExtensions)), blocks::swBresenhamLines::deviceExtensions, + static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, + blocks::swBresenhamLines::featureDesc, + 0, nullptr, + blocks::swBresenhamLines::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::swBresenhamLines::chainerDesc, + 0, nullptr, + }, + { + "hwBresenhamLines", + 0, nullptr, + static_cast<uint32_t>(std::size(blocks::hwBresenhamLines::deviceExtensions)), blocks::hwBresenhamLines::deviceExtensions, + static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, + blocks::hwBresenhamLines::featureDesc, + 0, nullptr, + blocks::hwBresenhamLines::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::hwBresenhamLines::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); + } // namespace swBresenhamLines_hwBresenhamLines_ + } // namespace blocks static const VpCapabilitiesDesc capabilities[] = { - MUST::variantCount, MUST::variants, - primitivesGeneratedQuery_pipelineStatisticsQuery_::variantCount, primitivesGeneratedQuery_pipelineStatisticsQuery_::variants, - swBresenhamLines_hwBresenhamLines_::variantCount, swBresenhamLines_hwBresenhamLines_::variants, + { blocks::MUST::variantCount, blocks::MUST::variants }, + { blocks::primitivesGeneratedQuery_pipelineStatisticsQuery_::variantCount, blocks::primitivesGeneratedQuery_pipelineStatisticsQuery_::variants }, + { blocks::swBresenhamLines_hwBresenhamLines_::variantCount, blocks::swBresenhamLines_hwBresenhamLines_::variants }, }; static const uint32_t capabilityCount = static_cast<uint32_t>(std::size(capabilities)); @@ -9108,9 +9641,85 @@ namespace VP_ANDROID_15_MINIMUMS { } // namespace VP_ANDROID_15_MINIMUMS #endif //VP_ANDROID_15_minimums +#ifdef VP_ANDROID_16_minimums +namespace VP_ANDROID_16_MINIMUMS { + namespace blocks { + namespace MUST { + static const VpVariantDesc variants[] = { + { + "MUST", + 0, nullptr, + static_cast<uint32_t>(std::size(blocks::MUST::deviceExtensions)), blocks::MUST::deviceExtensions, + static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, + blocks::MUST::featureDesc, + static_cast<uint32_t>(std::size(propertyStructTypes)), propertyStructTypes, + blocks::MUST::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::MUST::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); + } // namespace MUST + + namespace multisampledToSingleSampled_shaderStencilExport_ { + static const VpVariantDesc variants[] = { + { + "multisampledToSingleSampled", + 0, nullptr, + static_cast<uint32_t>(std::size(blocks::multisampledToSingleSampled::deviceExtensions)), blocks::multisampledToSingleSampled::deviceExtensions, + 0, nullptr, + blocks::multisampledToSingleSampled::featureDesc, + 0, nullptr, + blocks::multisampledToSingleSampled::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::multisampledToSingleSampled::chainerDesc, + 0, nullptr, + }, + { + "shaderStencilExport", + 0, nullptr, + static_cast<uint32_t>(std::size(blocks::shaderStencilExport::deviceExtensions)), blocks::shaderStencilExport::deviceExtensions, + 0, nullptr, + blocks::shaderStencilExport::featureDesc, + 0, nullptr, + blocks::shaderStencilExport::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::shaderStencilExport::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); + } // namespace multisampledToSingleSampled_shaderStencilExport_ + } // namespace blocks + + static const VpCapabilitiesDesc capabilities[] = { + { blocks::MUST::variantCount, blocks::MUST::variants }, + { blocks::multisampledToSingleSampled_shaderStencilExport_::variantCount, blocks::multisampledToSingleSampled_shaderStencilExport_::variants }, + }; + static const uint32_t capabilityCount = static_cast<uint32_t>(std::size(capabilities)); + + static const VpProfileProperties profiles[] = { + {VP_ANDROID_BASELINE_2022_NAME, VP_ANDROID_BASELINE_2022_SPEC_VERSION}, + {VP_ANDROID_15_MINIMUMS_NAME, VP_ANDROID_15_MINIMUMS_SPEC_VERSION}, + }; + static const uint32_t profileCount = static_cast<uint32_t>(std::size(profiles)); +} // namespace VP_ANDROID_16_MINIMUMS +#endif //VP_ANDROID_16_minimums + #ifdef VP_ANDROID_baseline_2021 namespace VP_ANDROID_BASELINE_2021 { static const VpVariantDesc mergedCapabilities[] = { + { "MERGED", static_cast<uint32_t>(std::size(instanceExtensions)), instanceExtensions, static_cast<uint32_t>(std::size(deviceExtensions)), deviceExtensions, @@ -9123,30 +9732,35 @@ namespace VP_ANDROID_BASELINE_2021 { 0, nullptr, 0, nullptr, chainerDesc, + 0, nullptr, + }, }; - namespace baseline { - static const VpVariantDesc variants[] = { - { - "baseline", - static_cast<uint32_t>(std::size(baseline::instanceExtensions)), baseline::instanceExtensions, - static_cast<uint32_t>(std::size(baseline::deviceExtensions)), baseline::deviceExtensions, - static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, - baseline::featureDesc, - static_cast<uint32_t>(std::size(propertyStructTypes)), propertyStructTypes, - baseline::propertyDesc, - 0, nullptr, - 0, nullptr, - static_cast<uint32_t>(std::size(formatStructTypes)), formatStructTypes, - static_cast<uint32_t>(std::size(baseline::formatDesc)), baseline::formatDesc, - baseline::chainerDesc, - }, - }; - static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); - } // namespace baseline + namespace blocks { + namespace baseline { + static const VpVariantDesc variants[] = { + { + "baseline", + static_cast<uint32_t>(std::size(blocks::baseline::instanceExtensions)), blocks::baseline::instanceExtensions, + static_cast<uint32_t>(std::size(blocks::baseline::deviceExtensions)), blocks::baseline::deviceExtensions, + static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, + blocks::baseline::featureDesc, + static_cast<uint32_t>(std::size(propertyStructTypes)), propertyStructTypes, + blocks::baseline::propertyDesc, + 0, nullptr, + 0, nullptr, + static_cast<uint32_t>(std::size(formatStructTypes)), formatStructTypes, + static_cast<uint32_t>(std::size(blocks::baseline::formatDesc)), blocks::baseline::formatDesc, + blocks::baseline::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); + } // namespace baseline + } // namespace blocks static const VpCapabilitiesDesc capabilities[] = { - baseline::variantCount, baseline::variants, + { blocks::baseline::variantCount, blocks::baseline::variants }, }; static const uint32_t capabilityCount = static_cast<uint32_t>(std::size(capabilities)); } // namespace VP_ANDROID_BASELINE_2021 @@ -9155,6 +9769,7 @@ namespace VP_ANDROID_BASELINE_2021 { #ifdef VP_ANDROID_baseline_2021_cpu_only namespace VP_ANDROID_BASELINE_2021_CPU_ONLY { static const VpVariantDesc mergedCapabilities[] = { + { "MERGED", static_cast<uint32_t>(std::size(instanceExtensions)), instanceExtensions, static_cast<uint32_t>(std::size(deviceExtensions)), deviceExtensions, @@ -9167,30 +9782,35 @@ namespace VP_ANDROID_BASELINE_2021_CPU_ONLY { 0, nullptr, 0, nullptr, chainerDesc, + 0, nullptr, + }, }; - namespace baseline { - static const VpVariantDesc variants[] = { - { - "baseline", - static_cast<uint32_t>(std::size(baseline::instanceExtensions)), baseline::instanceExtensions, - static_cast<uint32_t>(std::size(baseline::deviceExtensions)), baseline::deviceExtensions, - static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, - baseline::featureDesc, - static_cast<uint32_t>(std::size(propertyStructTypes)), propertyStructTypes, - baseline::propertyDesc, - 0, nullptr, - 0, nullptr, - static_cast<uint32_t>(std::size(formatStructTypes)), formatStructTypes, - static_cast<uint32_t>(std::size(baseline::formatDesc)), baseline::formatDesc, - baseline::chainerDesc, - }, - }; - static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); - } // namespace baseline + namespace blocks { + namespace baseline { + static const VpVariantDesc variants[] = { + { + "baseline", + static_cast<uint32_t>(std::size(blocks::baseline::instanceExtensions)), blocks::baseline::instanceExtensions, + static_cast<uint32_t>(std::size(blocks::baseline::deviceExtensions)), blocks::baseline::deviceExtensions, + static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, + blocks::baseline::featureDesc, + static_cast<uint32_t>(std::size(propertyStructTypes)), propertyStructTypes, + blocks::baseline::propertyDesc, + 0, nullptr, + 0, nullptr, + static_cast<uint32_t>(std::size(formatStructTypes)), formatStructTypes, + static_cast<uint32_t>(std::size(blocks::baseline::formatDesc)), blocks::baseline::formatDesc, + blocks::baseline::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); + } // namespace baseline + } // namespace blocks static const VpCapabilitiesDesc capabilities[] = { - baseline::variantCount, baseline::variants, + { blocks::baseline::variantCount, blocks::baseline::variants }, }; static const uint32_t capabilityCount = static_cast<uint32_t>(std::size(capabilities)); } // namespace VP_ANDROID_BASELINE_2021_CPU_ONLY @@ -9199,6 +9819,7 @@ namespace VP_ANDROID_BASELINE_2021_CPU_ONLY { #ifdef VP_ANDROID_baseline_2022 namespace VP_ANDROID_BASELINE_2022 { static const VpVariantDesc mergedCapabilities[] = { + { "MERGED", static_cast<uint32_t>(std::size(instanceExtensions)), instanceExtensions, static_cast<uint32_t>(std::size(deviceExtensions)), deviceExtensions, @@ -9211,30 +9832,35 @@ namespace VP_ANDROID_BASELINE_2022 { 0, nullptr, 0, nullptr, chainerDesc, + 0, nullptr, + }, }; - namespace baseline { - static const VpVariantDesc variants[] = { - { - "baseline", - static_cast<uint32_t>(std::size(baseline::instanceExtensions)), baseline::instanceExtensions, - static_cast<uint32_t>(std::size(baseline::deviceExtensions)), baseline::deviceExtensions, - static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, - baseline::featureDesc, - static_cast<uint32_t>(std::size(propertyStructTypes)), propertyStructTypes, - baseline::propertyDesc, - 0, nullptr, - 0, nullptr, - static_cast<uint32_t>(std::size(formatStructTypes)), formatStructTypes, - static_cast<uint32_t>(std::size(baseline::formatDesc)), baseline::formatDesc, - baseline::chainerDesc, - }, - }; - static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); - } // namespace baseline + namespace blocks { + namespace baseline { + static const VpVariantDesc variants[] = { + { + "baseline", + static_cast<uint32_t>(std::size(blocks::baseline::instanceExtensions)), blocks::baseline::instanceExtensions, + static_cast<uint32_t>(std::size(blocks::baseline::deviceExtensions)), blocks::baseline::deviceExtensions, + static_cast<uint32_t>(std::size(featureStructTypes)), featureStructTypes, + blocks::baseline::featureDesc, + static_cast<uint32_t>(std::size(propertyStructTypes)), propertyStructTypes, + blocks::baseline::propertyDesc, + 0, nullptr, + 0, nullptr, + static_cast<uint32_t>(std::size(formatStructTypes)), formatStructTypes, + static_cast<uint32_t>(std::size(blocks::baseline::formatDesc)), blocks::baseline::formatDesc, + blocks::baseline::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast<uint32_t>(std::size(variants)); + } // namespace baseline + } // namespace blocks static const VpCapabilitiesDesc capabilities[] = { - baseline::variantCount, baseline::variants, + { blocks::baseline::variantCount, blocks::baseline::variants }, }; static const uint32_t capabilityCount = static_cast<uint32_t>(std::size(capabilities)); } // namespace VP_ANDROID_BASELINE_2022 @@ -9251,6 +9877,16 @@ static const VpProfileDesc profiles[] = { 0, nullptr, }, #endif // VP_ANDROID_15_MINIMUMS +#ifdef VP_ANDROID_16_minimums + VpProfileDesc{ + VpProfileProperties{ VP_ANDROID_16_MINIMUMS_NAME, VP_ANDROID_16_MINIMUMS_SPEC_VERSION }, + VP_ANDROID_16_MINIMUMS_MIN_API_VERSION, + nullptr, + VP_ANDROID_16_MINIMUMS::profileCount, VP_ANDROID_16_MINIMUMS::profiles, + VP_ANDROID_16_MINIMUMS::capabilityCount, VP_ANDROID_16_MINIMUMS::capabilities, + 0, nullptr, + }, +#endif // VP_ANDROID_16_MINIMUMS #ifdef VP_ANDROID_baseline_2021 VpProfileDesc{ VpProfileProperties{ VP_ANDROID_BASELINE_2021_NAME, VP_ANDROID_BASELINE_2021_SPEC_VERSION }, @@ -9309,12 +9945,13 @@ struct FeaturesChain { VkPhysicalDeviceMultiDrawFeaturesEXT physicalDeviceMultiDrawFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT, nullptr }; VkPhysicalDeviceInlineUniformBlockFeatures physicalDeviceInlineUniformBlockFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, nullptr }; VkPhysicalDeviceMaintenance4Features physicalDeviceMaintenance4Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, nullptr }; - VkPhysicalDeviceMaintenance5FeaturesKHR physicalDeviceMaintenance5FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES_KHR, nullptr }; - VkPhysicalDeviceMaintenance6FeaturesKHR physicalDeviceMaintenance6FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMaintenance5Features physicalDeviceMaintenance5Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance6Features physicalDeviceMaintenance6Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance7FeaturesKHR physicalDeviceMaintenance7FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_7_FEATURES_KHR, nullptr }; VkPhysicalDeviceShaderDrawParametersFeatures physicalDeviceShaderDrawParametersFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, nullptr }; VkPhysicalDeviceShaderFloat16Int8Features physicalDeviceShaderFloat16Int8Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, nullptr }; VkPhysicalDeviceHostQueryResetFeatures physicalDeviceHostQueryResetFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, nullptr }; - VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR physicalDeviceGlobalPriorityQueryFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, nullptr }; + VkPhysicalDeviceGlobalPriorityQueryFeatures physicalDeviceGlobalPriorityQueryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES, nullptr }; VkPhysicalDeviceDeviceMemoryReportFeaturesEXT physicalDeviceDeviceMemoryReportFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, nullptr }; VkPhysicalDeviceDescriptorIndexingFeatures physicalDeviceDescriptorIndexingFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, nullptr }; VkPhysicalDeviceTimelineSemaphoreFeatures physicalDeviceTimelineSemaphoreFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, nullptr }; @@ -9324,13 +9961,12 @@ struct FeaturesChain { VkPhysicalDeviceShaderAtomicInt64Features physicalDeviceShaderAtomicInt64Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, nullptr }; VkPhysicalDeviceShaderAtomicFloatFeaturesEXT physicalDeviceShaderAtomicFloatFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT, nullptr }; VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT physicalDeviceShaderAtomicFloat2FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT, nullptr }; - VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR physicalDeviceVertexAttributeDivisorFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVertexAttributeDivisorFeatures physicalDeviceVertexAttributeDivisorFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES, nullptr }; VkPhysicalDeviceASTCDecodeFeaturesEXT physicalDeviceASTCDecodeFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, nullptr }; VkPhysicalDeviceTransformFeedbackFeaturesEXT physicalDeviceTransformFeedbackFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, nullptr }; VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV physicalDeviceRepresentativeFragmentTestFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, nullptr }; VkPhysicalDeviceExclusiveScissorFeaturesNV physicalDeviceExclusiveScissorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV, nullptr }; VkPhysicalDeviceCornerSampledImageFeaturesNV physicalDeviceCornerSampledImageFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, nullptr }; - VkPhysicalDeviceComputeShaderDerivativesFeaturesNV physicalDeviceComputeShaderDerivativesFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV, nullptr }; VkPhysicalDeviceShaderImageFootprintFeaturesNV physicalDeviceShaderImageFootprintFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, nullptr }; VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV physicalDeviceDedicatedAllocationImageAliasingFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, nullptr }; VkPhysicalDeviceCopyMemoryIndirectFeaturesNV physicalDeviceCopyMemoryIndirectFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV, nullptr }; @@ -9362,7 +9998,7 @@ struct FeaturesChain { VkPhysicalDeviceCoverageReductionModeFeaturesNV physicalDeviceCoverageReductionModeFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, nullptr }; VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL physicalDeviceShaderIntegerFunctions2FeaturesINTEL{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, nullptr }; VkPhysicalDeviceShaderClockFeaturesKHR physicalDeviceShaderClockFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, nullptr }; - VkPhysicalDeviceIndexTypeUint8FeaturesEXT physicalDeviceIndexTypeUint8FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, nullptr }; + VkPhysicalDeviceIndexTypeUint8Features physicalDeviceIndexTypeUint8Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES, nullptr }; VkPhysicalDeviceShaderSMBuiltinsFeaturesNV physicalDeviceShaderSMBuiltinsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV, nullptr }; VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT physicalDeviceFragmentShaderInterlockFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, nullptr }; VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures physicalDeviceSeparateDepthStencilLayoutsFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, nullptr }; @@ -9371,11 +10007,12 @@ struct FeaturesChain { VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures physicalDeviceShaderDemoteToHelperInvocationFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, nullptr }; VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT physicalDeviceTexelBufferAlignmentFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, nullptr }; VkPhysicalDeviceSubgroupSizeControlFeatures physicalDeviceSubgroupSizeControlFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, nullptr }; - VkPhysicalDeviceLineRasterizationFeaturesEXT physicalDeviceLineRasterizationFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT, nullptr }; + VkPhysicalDeviceLineRasterizationFeatures physicalDeviceLineRasterizationFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES, nullptr }; VkPhysicalDevicePipelineCreationCacheControlFeatures physicalDevicePipelineCreationCacheControlFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, nullptr }; VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, nullptr }; VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr }; VkPhysicalDeviceVulkan13Features physicalDeviceVulkan13Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, nullptr }; + VkPhysicalDeviceVulkan14Features physicalDeviceVulkan14Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES, nullptr }; VkPhysicalDeviceCoherentMemoryFeaturesAMD physicalDeviceCoherentMemoryFeaturesAMD{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, nullptr }; VkPhysicalDeviceCustomBorderColorFeaturesEXT physicalDeviceCustomBorderColorFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT, nullptr }; VkPhysicalDeviceBorderColorSwizzleFeaturesEXT physicalDeviceBorderColorSwizzleFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT, nullptr }; @@ -9401,17 +10038,19 @@ struct FeaturesChain { VkPhysicalDeviceImage2DViewOf3DFeaturesEXT physicalDeviceImage2DViewOf3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, nullptr }; VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT physicalDeviceImageSlicedViewOf3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT, nullptr }; VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT physicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceLegacyVertexAttributesFeaturesEXT physicalDeviceLegacyVertexAttributesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_FEATURES_EXT, nullptr }; VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT physicalDeviceMutableDescriptorTypeFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT, nullptr }; VkPhysicalDeviceDepthClipControlFeaturesEXT physicalDeviceDepthClipControlFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT, nullptr }; VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT physicalDeviceVertexInputDynamicStateFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT, nullptr }; VkPhysicalDeviceExternalMemoryRDMAFeaturesNV physicalDeviceExternalMemoryRDMAFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV, nullptr }; + VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR physicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR, nullptr }; VkPhysicalDeviceColorWriteEnableFeaturesEXT physicalDeviceColorWriteEnableFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, nullptr }; VkPhysicalDeviceSynchronization2Features physicalDeviceSynchronization2Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, nullptr }; - VkPhysicalDeviceHostImageCopyFeaturesEXT physicalDeviceHostImageCopyFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceHostImageCopyFeatures physicalDeviceHostImageCopyFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES, nullptr }; VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT physicalDevicePrimitivesGeneratedQueryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT, nullptr }; VkPhysicalDeviceLegacyDitheringFeaturesEXT physicalDeviceLegacyDitheringFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT, nullptr }; VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT, nullptr }; - VkPhysicalDevicePipelineProtectedAccessFeaturesEXT physicalDevicePipelineProtectedAccessFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineProtectedAccessFeatures physicalDevicePipelineProtectedAccessFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES, nullptr }; VkPhysicalDeviceVideoMaintenance1FeaturesKHR physicalDeviceVideoMaintenance1FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR, nullptr }; VkPhysicalDeviceInheritedViewportScissorFeaturesNV physicalDeviceInheritedViewportScissorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV, nullptr }; VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT physicalDeviceYcbcr2Plane444FormatsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT, nullptr }; @@ -9420,12 +10059,14 @@ struct FeaturesChain { VkPhysicalDeviceShaderIntegerDotProductFeatures physicalDeviceShaderIntegerDotProductFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, nullptr }; VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR physicalDeviceFragmentShaderBarycentricFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, nullptr }; VkPhysicalDeviceRayTracingMotionBlurFeaturesNV physicalDeviceRayTracingMotionBlurFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV, nullptr }; + VkPhysicalDeviceRayTracingValidationFeaturesNV physicalDeviceRayTracingValidationFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_VALIDATION_FEATURES_NV, nullptr }; VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT physicalDeviceRGBA10X6FormatsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT, nullptr }; VkPhysicalDeviceDynamicRenderingFeatures physicalDeviceDynamicRenderingFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, nullptr }; VkPhysicalDeviceImageViewMinLodFeaturesEXT physicalDeviceImageViewMinLodFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT, nullptr }; VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT physicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, nullptr }; VkPhysicalDeviceLinearColorAttachmentFeaturesNV physicalDeviceLinearColorAttachmentFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV, nullptr }; VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT physicalDeviceGraphicsPipelineLibraryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineBinaryFeaturesKHR physicalDevicePipelineBinaryFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_BINARY_FEATURES_KHR, nullptr }; VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE physicalDeviceDescriptorSetHostMappingFeaturesVALVE{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE, nullptr }; VkPhysicalDeviceNestedCommandBufferFeaturesEXT physicalDeviceNestedCommandBufferFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT, nullptr }; VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT physicalDeviceShaderModuleIdentifierFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT, nullptr }; @@ -9439,7 +10080,7 @@ struct FeaturesChain { VkPhysicalDevicePipelinePropertiesFeaturesEXT physicalDevicePipelinePropertiesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT, nullptr }; VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD, nullptr }; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT physicalDeviceNonSeamlessCubeMapFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT, nullptr }; - VkPhysicalDevicePipelineRobustnessFeaturesEXT physicalDevicePipelineRobustnessFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineRobustnessFeatures physicalDevicePipelineRobustnessFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES, nullptr }; VkPhysicalDeviceImageProcessingFeaturesQCOM physicalDeviceImageProcessingFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM, nullptr }; VkPhysicalDeviceTilePropertiesFeaturesQCOM physicalDeviceTilePropertiesFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM, nullptr }; VkPhysicalDeviceAmigoProfilingFeaturesSEC physicalDeviceAmigoProfilingFeaturesSEC{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC, nullptr }; @@ -9468,6 +10109,7 @@ struct FeaturesChain { #ifdef VK_ENABLE_BETA_EXTENSIONS VkPhysicalDeviceShaderEnqueueFeaturesAMDX physicalDeviceShaderEnqueueFeaturesAMDX{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ENQUEUE_FEATURES_AMDX, nullptr }; #endif + VkPhysicalDeviceAntiLagFeaturesAMD physicalDeviceAntiLagFeaturesAMD{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ANTI_LAG_FEATURES_AMD, nullptr }; VkPhysicalDeviceCubicClampFeaturesQCOM physicalDeviceCubicClampFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_CLAMP_FEATURES_QCOM, nullptr }; VkPhysicalDeviceYcbcrDegammaFeaturesQCOM physicalDeviceYcbcrDegammaFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_DEGAMMA_FEATURES_QCOM, nullptr }; VkPhysicalDeviceCubicWeightsFeaturesQCOM physicalDeviceCubicWeightsFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_WEIGHTS_FEATURES_QCOM, nullptr }; @@ -9481,6 +10123,18 @@ struct FeaturesChain { VkPhysicalDeviceSchedulingControlsFeaturesARM physicalDeviceSchedulingControlsFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_FEATURES_ARM, nullptr }; VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG physicalDeviceRelaxedLineRasterizationFeaturesIMG{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG, nullptr }; VkPhysicalDeviceRenderPassStripedFeaturesARM physicalDeviceRenderPassStripedFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_FEATURES_ARM, nullptr }; + VkPhysicalDeviceShaderMaximalReconvergenceFeaturesKHR physicalDeviceShaderMaximalReconvergenceFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderSubgroupRotateFeatures physicalDeviceShaderSubgroupRotateFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES, nullptr }; + VkPhysicalDeviceShaderExpectAssumeFeatures physicalDeviceShaderExpectAssumeFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES, nullptr }; + VkPhysicalDeviceShaderFloatControls2Features physicalDeviceShaderFloatControls2Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES, nullptr }; + VkPhysicalDeviceDynamicRenderingLocalReadFeatures physicalDeviceDynamicRenderingLocalReadFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES, nullptr }; + VkPhysicalDeviceShaderQuadControlFeaturesKHR physicalDeviceShaderQuadControlFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_QUAD_CONTROL_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV physicalDeviceShaderAtomicFloat16VectorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV, nullptr }; + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT physicalDeviceMapMemoryPlacedFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT, nullptr }; + VkPhysicalDeviceRawAccessChainsFeaturesNV physicalDeviceRawAccessChainsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAW_ACCESS_CHAINS_FEATURES_NV, nullptr }; + VkPhysicalDeviceCommandBufferInheritanceFeaturesNV physicalDeviceCommandBufferInheritanceFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMMAND_BUFFER_INHERITANCE_FEATURES_NV, nullptr }; + VkPhysicalDeviceImageAlignmentControlFeaturesMESA physicalDeviceImageAlignmentControlFeaturesMESA{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_FEATURES_MESA, nullptr }; + VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT physicalDeviceShaderReplicatedCompositesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT, nullptr }; VkPhysicalDeviceFeatures2KHR physicalDeviceFeatures2KHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, nullptr }; FeaturesChain() { @@ -9500,12 +10154,13 @@ struct FeaturesChain { this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT, size<VkPhysicalDeviceMultiDrawFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, size<VkPhysicalDeviceInlineUniformBlockFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, size<VkPhysicalDeviceMaintenance4Features>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES_KHR, size<VkPhysicalDeviceMaintenance5FeaturesKHR>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES_KHR, size<VkPhysicalDeviceMaintenance6FeaturesKHR>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES, size<VkPhysicalDeviceMaintenance5Features>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES, size<VkPhysicalDeviceMaintenance6Features>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_7_FEATURES_KHR, size<VkPhysicalDeviceMaintenance7FeaturesKHR>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, size<VkPhysicalDeviceShaderDrawParametersFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, size<VkPhysicalDeviceShaderFloat16Int8Features>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, size<VkPhysicalDeviceHostQueryResetFeatures>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, size<VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES, size<VkPhysicalDeviceGlobalPriorityQueryFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, size<VkPhysicalDeviceDeviceMemoryReportFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, size<VkPhysicalDeviceDescriptorIndexingFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, size<VkPhysicalDeviceTimelineSemaphoreFeatures>() }); @@ -9515,13 +10170,12 @@ struct FeaturesChain { this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, size<VkPhysicalDeviceShaderAtomicInt64Features>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT, size<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT, size<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_KHR, size<VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES, size<VkPhysicalDeviceVertexAttributeDivisorFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, size<VkPhysicalDeviceASTCDecodeFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, size<VkPhysicalDeviceTransformFeedbackFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, size<VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV, size<VkPhysicalDeviceExclusiveScissorFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, size<VkPhysicalDeviceCornerSampledImageFeaturesNV>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV, size<VkPhysicalDeviceComputeShaderDerivativesFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, size<VkPhysicalDeviceShaderImageFootprintFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, size<VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV, size<VkPhysicalDeviceCopyMemoryIndirectFeaturesNV>() }); @@ -9553,7 +10207,7 @@ struct FeaturesChain { this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, size<VkPhysicalDeviceCoverageReductionModeFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, size<VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, size<VkPhysicalDeviceShaderClockFeaturesKHR>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT, size<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES, size<VkPhysicalDeviceIndexTypeUint8Features>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV, size<VkPhysicalDeviceShaderSMBuiltinsFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, size<VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, size<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures>() }); @@ -9562,11 +10216,12 @@ struct FeaturesChain { this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, size<VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, size<VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, size<VkPhysicalDeviceSubgroupSizeControlFeatures>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT, size<VkPhysicalDeviceLineRasterizationFeaturesEXT>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES, size<VkPhysicalDeviceLineRasterizationFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, size<VkPhysicalDevicePipelineCreationCacheControlFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, size<VkPhysicalDeviceVulkan11Features>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, size<VkPhysicalDeviceVulkan12Features>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, size<VkPhysicalDeviceVulkan13Features>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES, size<VkPhysicalDeviceVulkan14Features>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, size<VkPhysicalDeviceCoherentMemoryFeaturesAMD>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT, size<VkPhysicalDeviceCustomBorderColorFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT, size<VkPhysicalDeviceBorderColorSwizzleFeaturesEXT>() }); @@ -9592,17 +10247,19 @@ struct FeaturesChain { this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, size<VkPhysicalDeviceImage2DViewOf3DFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT, size<VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT, size<VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_FEATURES_EXT, size<VkPhysicalDeviceLegacyVertexAttributesFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT, size<VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT, size<VkPhysicalDeviceDepthClipControlFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT, size<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV, size<VkPhysicalDeviceExternalMemoryRDMAFeaturesNV>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR, size<VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, size<VkPhysicalDeviceColorWriteEnableFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, size<VkPhysicalDeviceSynchronization2Features>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT, size<VkPhysicalDeviceHostImageCopyFeaturesEXT>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES, size<VkPhysicalDeviceHostImageCopyFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT, size<VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT, size<VkPhysicalDeviceLegacyDitheringFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT, size<VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT, size<VkPhysicalDevicePipelineProtectedAccessFeaturesEXT>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES, size<VkPhysicalDevicePipelineProtectedAccessFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR, size<VkPhysicalDeviceVideoMaintenance1FeaturesKHR>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV, size<VkPhysicalDeviceInheritedViewportScissorFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT, size<VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT>() }); @@ -9611,12 +10268,14 @@ struct FeaturesChain { this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, size<VkPhysicalDeviceShaderIntegerDotProductFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, size<VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV, size<VkPhysicalDeviceRayTracingMotionBlurFeaturesNV>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_VALIDATION_FEATURES_NV, size<VkPhysicalDeviceRayTracingValidationFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT, size<VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, size<VkPhysicalDeviceDynamicRenderingFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT, size<VkPhysicalDeviceImageViewMinLodFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, size<VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV, size<VkPhysicalDeviceLinearColorAttachmentFeaturesNV>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT, size<VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_BINARY_FEATURES_KHR, size<VkPhysicalDevicePipelineBinaryFeaturesKHR>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE, size<VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT, size<VkPhysicalDeviceNestedCommandBufferFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT, size<VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT>() }); @@ -9630,7 +10289,7 @@ struct FeaturesChain { this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT, size<VkPhysicalDevicePipelinePropertiesFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD, size<VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT, size<VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT>() }); - this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT, size<VkPhysicalDevicePipelineRobustnessFeaturesEXT>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES, size<VkPhysicalDevicePipelineRobustnessFeatures>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM, size<VkPhysicalDeviceImageProcessingFeaturesQCOM>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM, size<VkPhysicalDeviceTilePropertiesFeaturesQCOM>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC, size<VkPhysicalDeviceAmigoProfilingFeaturesSEC>() }); @@ -9659,6 +10318,7 @@ struct FeaturesChain { #ifdef VK_ENABLE_BETA_EXTENSIONS this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ENQUEUE_FEATURES_AMDX, size<VkPhysicalDeviceShaderEnqueueFeaturesAMDX>() }); #endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ANTI_LAG_FEATURES_AMD, size<VkPhysicalDeviceAntiLagFeaturesAMD>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_CLAMP_FEATURES_QCOM, size<VkPhysicalDeviceCubicClampFeaturesQCOM>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_DEGAMMA_FEATURES_QCOM, size<VkPhysicalDeviceYcbcrDegammaFeaturesQCOM>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_WEIGHTS_FEATURES_QCOM, size<VkPhysicalDeviceCubicWeightsFeaturesQCOM>() }); @@ -9672,6 +10332,18 @@ struct FeaturesChain { this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_FEATURES_ARM, size<VkPhysicalDeviceSchedulingControlsFeaturesARM>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG, size<VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_FEATURES_ARM, size<VkPhysicalDeviceRenderPassStripedFeaturesARM>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR, size<VkPhysicalDeviceShaderMaximalReconvergenceFeaturesKHR>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES, size<VkPhysicalDeviceShaderSubgroupRotateFeatures>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES, size<VkPhysicalDeviceShaderExpectAssumeFeatures>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES, size<VkPhysicalDeviceShaderFloatControls2Features>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES, size<VkPhysicalDeviceDynamicRenderingLocalReadFeatures>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_QUAD_CONTROL_FEATURES_KHR, size<VkPhysicalDeviceShaderQuadControlFeaturesKHR>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV, size<VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT, size<VkPhysicalDeviceMapMemoryPlacedFeaturesEXT>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAW_ACCESS_CHAINS_FEATURES_NV, size<VkPhysicalDeviceRawAccessChainsFeaturesNV>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMMAND_BUFFER_INHERITANCE_FEATURES_NV, size<VkPhysicalDeviceCommandBufferInheritanceFeaturesNV>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_FEATURES_MESA, size<VkPhysicalDeviceImageAlignmentControlFeaturesMESA>() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT, size<VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT>() }); this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, size<VkPhysicalDeviceFeatures2KHR>() }); //Initializing the full list of available structure features @@ -9706,18 +10378,20 @@ struct FeaturesChain { pNext = &physicalDeviceInlineUniformBlockFeatures; physicalDeviceMaintenance4Features.pNext = pNext; pNext = &physicalDeviceMaintenance4Features; - physicalDeviceMaintenance5FeaturesKHR.pNext = pNext; - pNext = &physicalDeviceMaintenance5FeaturesKHR; - physicalDeviceMaintenance6FeaturesKHR.pNext = pNext; - pNext = &physicalDeviceMaintenance6FeaturesKHR; + physicalDeviceMaintenance5Features.pNext = pNext; + pNext = &physicalDeviceMaintenance5Features; + physicalDeviceMaintenance6Features.pNext = pNext; + pNext = &physicalDeviceMaintenance6Features; + physicalDeviceMaintenance7FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance7FeaturesKHR; physicalDeviceShaderDrawParametersFeatures.pNext = pNext; pNext = &physicalDeviceShaderDrawParametersFeatures; physicalDeviceShaderFloat16Int8Features.pNext = pNext; pNext = &physicalDeviceShaderFloat16Int8Features; physicalDeviceHostQueryResetFeatures.pNext = pNext; pNext = &physicalDeviceHostQueryResetFeatures; - physicalDeviceGlobalPriorityQueryFeaturesKHR.pNext = pNext; - pNext = &physicalDeviceGlobalPriorityQueryFeaturesKHR; + physicalDeviceGlobalPriorityQueryFeatures.pNext = pNext; + pNext = &physicalDeviceGlobalPriorityQueryFeatures; physicalDeviceDeviceMemoryReportFeaturesEXT.pNext = pNext; pNext = &physicalDeviceDeviceMemoryReportFeaturesEXT; physicalDeviceDescriptorIndexingFeatures.pNext = pNext; @@ -9736,8 +10410,8 @@ struct FeaturesChain { pNext = &physicalDeviceShaderAtomicFloatFeaturesEXT; physicalDeviceShaderAtomicFloat2FeaturesEXT.pNext = pNext; pNext = &physicalDeviceShaderAtomicFloat2FeaturesEXT; - physicalDeviceVertexAttributeDivisorFeaturesKHR.pNext = pNext; - pNext = &physicalDeviceVertexAttributeDivisorFeaturesKHR; + physicalDeviceVertexAttributeDivisorFeatures.pNext = pNext; + pNext = &physicalDeviceVertexAttributeDivisorFeatures; physicalDeviceASTCDecodeFeaturesEXT.pNext = pNext; pNext = &physicalDeviceASTCDecodeFeaturesEXT; physicalDeviceTransformFeedbackFeaturesEXT.pNext = pNext; @@ -9748,8 +10422,6 @@ struct FeaturesChain { pNext = &physicalDeviceExclusiveScissorFeaturesNV; physicalDeviceCornerSampledImageFeaturesNV.pNext = pNext; pNext = &physicalDeviceCornerSampledImageFeaturesNV; - physicalDeviceComputeShaderDerivativesFeaturesNV.pNext = pNext; - pNext = &physicalDeviceComputeShaderDerivativesFeaturesNV; physicalDeviceShaderImageFootprintFeaturesNV.pNext = pNext; pNext = &physicalDeviceShaderImageFootprintFeaturesNV; physicalDeviceDedicatedAllocationImageAliasingFeaturesNV.pNext = pNext; @@ -9812,8 +10484,8 @@ struct FeaturesChain { pNext = &physicalDeviceShaderIntegerFunctions2FeaturesINTEL; physicalDeviceShaderClockFeaturesKHR.pNext = pNext; pNext = &physicalDeviceShaderClockFeaturesKHR; - physicalDeviceIndexTypeUint8FeaturesEXT.pNext = pNext; - pNext = &physicalDeviceIndexTypeUint8FeaturesEXT; + physicalDeviceIndexTypeUint8Features.pNext = pNext; + pNext = &physicalDeviceIndexTypeUint8Features; physicalDeviceShaderSMBuiltinsFeaturesNV.pNext = pNext; pNext = &physicalDeviceShaderSMBuiltinsFeaturesNV; physicalDeviceFragmentShaderInterlockFeaturesEXT.pNext = pNext; @@ -9830,8 +10502,8 @@ struct FeaturesChain { pNext = &physicalDeviceTexelBufferAlignmentFeaturesEXT; physicalDeviceSubgroupSizeControlFeatures.pNext = pNext; pNext = &physicalDeviceSubgroupSizeControlFeatures; - physicalDeviceLineRasterizationFeaturesEXT.pNext = pNext; - pNext = &physicalDeviceLineRasterizationFeaturesEXT; + physicalDeviceLineRasterizationFeatures.pNext = pNext; + pNext = &physicalDeviceLineRasterizationFeatures; physicalDevicePipelineCreationCacheControlFeatures.pNext = pNext; pNext = &physicalDevicePipelineCreationCacheControlFeatures; physicalDeviceVulkan11Features.pNext = pNext; @@ -9840,6 +10512,8 @@ struct FeaturesChain { pNext = &physicalDeviceVulkan12Features; physicalDeviceVulkan13Features.pNext = pNext; pNext = &physicalDeviceVulkan13Features; + physicalDeviceVulkan14Features.pNext = pNext; + pNext = &physicalDeviceVulkan14Features; physicalDeviceCoherentMemoryFeaturesAMD.pNext = pNext; pNext = &physicalDeviceCoherentMemoryFeaturesAMD; physicalDeviceCustomBorderColorFeaturesEXT.pNext = pNext; @@ -9888,6 +10562,8 @@ struct FeaturesChain { pNext = &physicalDeviceImageSlicedViewOf3DFeaturesEXT; physicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT.pNext = pNext; pNext = &physicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT; + physicalDeviceLegacyVertexAttributesFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceLegacyVertexAttributesFeaturesEXT; physicalDeviceMutableDescriptorTypeFeaturesEXT.pNext = pNext; pNext = &physicalDeviceMutableDescriptorTypeFeaturesEXT; physicalDeviceDepthClipControlFeaturesEXT.pNext = pNext; @@ -9896,20 +10572,22 @@ struct FeaturesChain { pNext = &physicalDeviceVertexInputDynamicStateFeaturesEXT; physicalDeviceExternalMemoryRDMAFeaturesNV.pNext = pNext; pNext = &physicalDeviceExternalMemoryRDMAFeaturesNV; + physicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR; physicalDeviceColorWriteEnableFeaturesEXT.pNext = pNext; pNext = &physicalDeviceColorWriteEnableFeaturesEXT; physicalDeviceSynchronization2Features.pNext = pNext; pNext = &physicalDeviceSynchronization2Features; - physicalDeviceHostImageCopyFeaturesEXT.pNext = pNext; - pNext = &physicalDeviceHostImageCopyFeaturesEXT; + physicalDeviceHostImageCopyFeatures.pNext = pNext; + pNext = &physicalDeviceHostImageCopyFeatures; physicalDevicePrimitivesGeneratedQueryFeaturesEXT.pNext = pNext; pNext = &physicalDevicePrimitivesGeneratedQueryFeaturesEXT; physicalDeviceLegacyDitheringFeaturesEXT.pNext = pNext; pNext = &physicalDeviceLegacyDitheringFeaturesEXT; physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT.pNext = pNext; pNext = &physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT; - physicalDevicePipelineProtectedAccessFeaturesEXT.pNext = pNext; - pNext = &physicalDevicePipelineProtectedAccessFeaturesEXT; + physicalDevicePipelineProtectedAccessFeatures.pNext = pNext; + pNext = &physicalDevicePipelineProtectedAccessFeatures; physicalDeviceVideoMaintenance1FeaturesKHR.pNext = pNext; pNext = &physicalDeviceVideoMaintenance1FeaturesKHR; physicalDeviceInheritedViewportScissorFeaturesNV.pNext = pNext; @@ -9926,6 +10604,8 @@ struct FeaturesChain { pNext = &physicalDeviceFragmentShaderBarycentricFeaturesKHR; physicalDeviceRayTracingMotionBlurFeaturesNV.pNext = pNext; pNext = &physicalDeviceRayTracingMotionBlurFeaturesNV; + physicalDeviceRayTracingValidationFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRayTracingValidationFeaturesNV; physicalDeviceRGBA10X6FormatsFeaturesEXT.pNext = pNext; pNext = &physicalDeviceRGBA10X6FormatsFeaturesEXT; physicalDeviceDynamicRenderingFeatures.pNext = pNext; @@ -9938,6 +10618,8 @@ struct FeaturesChain { pNext = &physicalDeviceLinearColorAttachmentFeaturesNV; physicalDeviceGraphicsPipelineLibraryFeaturesEXT.pNext = pNext; pNext = &physicalDeviceGraphicsPipelineLibraryFeaturesEXT; + physicalDevicePipelineBinaryFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePipelineBinaryFeaturesKHR; physicalDeviceDescriptorSetHostMappingFeaturesVALVE.pNext = pNext; pNext = &physicalDeviceDescriptorSetHostMappingFeaturesVALVE; physicalDeviceNestedCommandBufferFeaturesEXT.pNext = pNext; @@ -9962,8 +10644,8 @@ struct FeaturesChain { pNext = &physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD; physicalDeviceNonSeamlessCubeMapFeaturesEXT.pNext = pNext; pNext = &physicalDeviceNonSeamlessCubeMapFeaturesEXT; - physicalDevicePipelineRobustnessFeaturesEXT.pNext = pNext; - pNext = &physicalDevicePipelineRobustnessFeaturesEXT; + physicalDevicePipelineRobustnessFeatures.pNext = pNext; + pNext = &physicalDevicePipelineRobustnessFeatures; physicalDeviceImageProcessingFeaturesQCOM.pNext = pNext; pNext = &physicalDeviceImageProcessingFeaturesQCOM; physicalDeviceTilePropertiesFeaturesQCOM.pNext = pNext; @@ -10016,6 +10698,8 @@ struct FeaturesChain { physicalDeviceShaderEnqueueFeaturesAMDX.pNext = pNext; pNext = &physicalDeviceShaderEnqueueFeaturesAMDX; #endif + physicalDeviceAntiLagFeaturesAMD.pNext = pNext; + pNext = &physicalDeviceAntiLagFeaturesAMD; physicalDeviceCubicClampFeaturesQCOM.pNext = pNext; pNext = &physicalDeviceCubicClampFeaturesQCOM; physicalDeviceYcbcrDegammaFeaturesQCOM.pNext = pNext; @@ -10040,6 +10724,30 @@ struct FeaturesChain { pNext = &physicalDeviceRelaxedLineRasterizationFeaturesIMG; physicalDeviceRenderPassStripedFeaturesARM.pNext = pNext; pNext = &physicalDeviceRenderPassStripedFeaturesARM; + physicalDeviceShaderMaximalReconvergenceFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderMaximalReconvergenceFeaturesKHR; + physicalDeviceShaderSubgroupRotateFeatures.pNext = pNext; + pNext = &physicalDeviceShaderSubgroupRotateFeatures; + physicalDeviceShaderExpectAssumeFeatures.pNext = pNext; + pNext = &physicalDeviceShaderExpectAssumeFeatures; + physicalDeviceShaderFloatControls2Features.pNext = pNext; + pNext = &physicalDeviceShaderFloatControls2Features; + physicalDeviceDynamicRenderingLocalReadFeatures.pNext = pNext; + pNext = &physicalDeviceDynamicRenderingLocalReadFeatures; + physicalDeviceShaderQuadControlFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderQuadControlFeaturesKHR; + physicalDeviceShaderAtomicFloat16VectorFeaturesNV.pNext = pNext; + pNext = &physicalDeviceShaderAtomicFloat16VectorFeaturesNV; + physicalDeviceMapMemoryPlacedFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMapMemoryPlacedFeaturesEXT; + physicalDeviceRawAccessChainsFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRawAccessChainsFeaturesNV; + physicalDeviceCommandBufferInheritanceFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCommandBufferInheritanceFeaturesNV; + physicalDeviceImageAlignmentControlFeaturesMESA.pNext = pNext; + pNext = &physicalDeviceImageAlignmentControlFeaturesMESA; + physicalDeviceShaderReplicatedCompositesFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderReplicatedCompositesFeaturesEXT; physicalDeviceFeatures2KHR.pNext = pNext; } @@ -10090,8 +10798,8 @@ struct FeaturesChain { const std::size_t offset = sizeof(VkBaseOutStructure); const VkBaseOutStructure* q = reinterpret_cast<const VkBaseOutStructure*>(pCreateInfo->pCreateInfo->pNext); while (q) { - std::size_t count = this->structureSize[q->sType]; - for (std::size_t i = 0, n = count; i < n; ++i) { + const std::size_t count = this->structureSize[q->sType]; + for (std::size_t index = 0; index < count; ++index) { const VkBaseOutStructure* pInputStruct = reinterpret_cast<const VkBaseOutStructure*>(q); VkBaseOutStructure* pOutputStruct = reinterpret_cast<VkBaseOutStructure*>(detail::vpGetStructure(&this->requiredFeaturesChain, q->sType)); const uint8_t* pInputData = reinterpret_cast<const uint8_t*>(pInputStruct) + offset; @@ -10099,7 +10807,7 @@ struct FeaturesChain { const VkBool32* input = reinterpret_cast<const VkBool32*>(pInputData); VkBool32* output = reinterpret_cast<VkBool32*>(pOutputData); - output[i] = (output[i] == VK_TRUE || input[i] == VK_TRUE) ? VK_TRUE : VK_FALSE; + output[index] = (output[index] == VK_TRUE || input[index] == VK_TRUE) ? VK_TRUE : VK_FALSE; } q = q->pNext; } @@ -10107,7 +10815,7 @@ struct FeaturesChain { this->ApplyRobustness(pCreateInfo); } - void PushBack(VkBaseOutStructure* found) { + void PushBack(VkBaseOutStructure* found) { VkBaseOutStructure* last = reinterpret_cast<VkBaseOutStructure*>(&requiredFeaturesChain); while (last->pNext != nullptr) { last = last->pNext; @@ -10133,27 +10841,29 @@ struct FeaturesChain { }; // struct FeaturesChain VPAPI_ATTR const VpProfileDesc* vpGetProfileDesc(const char profileName[VP_MAX_PROFILE_NAME_SIZE]) { - for (uint32_t i = 0; i < profileCount; ++i) { - if (strncmp(profiles[i].props.profileName, profileName, VP_MAX_PROFILE_NAME_SIZE) == 0) return &profiles[i]; + for (uint32_t profileIndex = 0; profileIndex < profileCount; ++profileIndex) { + if (strncmp(profiles[profileIndex].props.profileName, profileName, VP_MAX_PROFILE_NAME_SIZE) == 0) { + return &profiles[profileIndex]; + } } return nullptr; } VPAPI_ATTR std::vector<VpProfileProperties> GatherProfiles(const VpProfileProperties& profile, const char* pBlockName = nullptr) { - std::vector<VpProfileProperties> profiles; + std::vector<VpProfileProperties> gatheredProfiles; if (pBlockName == nullptr) { - const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(profile.profileName); - if (profile_desc != nullptr) { - for (uint32_t profile_index = 0; profile_index < profile_desc->requiredProfileCount; ++profile_index) { - profiles.push_back(profile_desc->pRequiredProfiles[profile_index]); + const detail::VpProfileDesc* profileDesc = detail::vpGetProfileDesc(profile.profileName); + if (profileDesc != nullptr) { + for (uint32_t profileIndex = 0; profileIndex < profileDesc->requiredProfileCount; ++profileIndex) { + gatheredProfiles.push_back(profileDesc->pRequiredProfiles[profileIndex]); } } } - profiles.push_back(profile); + gatheredProfiles.push_back(profile); - return profiles; + return gatheredProfiles; } VPAPI_ATTR bool vpCheckVersion(uint32_t actual, uint32_t expected) { @@ -10184,7 +10894,6 @@ VPAPI_ATTR bool CheckExtension(const VkExtensionProperties* supportedProperties, // if (supportedProperties[i].specVersion >= expectedVersion) found = true; } } - VP_DEBUG_COND_MSGF(!found, "Unsupported extension: %s", requestedExtension); return found; } @@ -10198,11 +10907,11 @@ VPAPI_ATTR bool CheckExtension(const std::vector<const char*>& extensions, const } VPAPI_ATTR void GetExtensions(uint32_t extensionCount, const VkExtensionProperties *pExtensions, std::vector<const char *> &extensions) { - for (uint32_t i = 0; i < extensionCount; ++i) { - if (CheckExtension(extensions, pExtensions[i].extensionName)) { + for (uint32_t ext_index = 0; ext_index < extensionCount; ++ext_index) { + if (CheckExtension(extensions, pExtensions[ext_index].extensionName)) { continue; } - extensions.push_back(pExtensions[i].extensionName); + extensions.push_back(pExtensions[ext_index].extensionName); } } @@ -10211,25 +10920,29 @@ VPAPI_ATTR std::vector<VpBlockProperties> GatherBlocks( uint32_t enabledProfileBlockCount, const VpBlockProperties* pEnabledProfileBlocks) { std::vector<VpBlockProperties> results; - for (std::size_t i = 0; i < enabledFullProfileCount; ++i) { - const std::vector<VpProfileProperties>& profiles = GatherProfiles(pEnabledFullProfiles[i]); + for (std::size_t profile_index = 0; profile_index < enabledFullProfileCount; ++profile_index) { + const std::vector<VpProfileProperties>& gathered_profiles = GatherProfiles(pEnabledFullProfiles[profile_index]); - for (std::size_t j = 0; j < profiles.size(); ++j) { - VpBlockProperties block{profiles[j], 0, ""}; + for (std::size_t gathered_index = 0; gathered_index < gathered_profiles.size(); ++gathered_index) { + VpBlockProperties block{gathered_profiles[gathered_index], 0, ""}; results.push_back(block); } } - for (std::size_t i = 0; i < enabledProfileBlockCount; ++i) { - results.push_back(pEnabledProfileBlocks[i]); + for (std::size_t block_index = 0; block_index < enabledProfileBlockCount; ++block_index) { + results.push_back(pEnabledProfileBlocks[block_index]); } return results; } VPAPI_ATTR VkResult vpGetInstanceProfileSupportSingleProfile( - uint32_t api_version, const std::vector<VkExtensionProperties>& supported_extensions, - const VpProfileProperties* pProfile, VkBool32* pSupported, std::vector<VpBlockProperties>& supportedBlocks, std::vector<VpBlockProperties>& unsupportedBlocks) { + uint32_t api_version, + const std::vector<VkExtensionProperties>& supported_extensions, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + std::vector<VpBlockProperties>& supportedBlocks, + std::vector<VpBlockProperties>& unsupportedBlocks) { assert(pProfile != nullptr); const detail::VpProfileDesc* pProfileDesc = vpGetProfileDesc(pProfile->profileName); @@ -10248,16 +10961,7 @@ VPAPI_ATTR VkResult vpGetInstanceProfileSupportSingleProfile( // Required API version is built in root profile, not need to check dependent profile API versions if (api_version != 0) { if (!vpCheckVersion(api_version, pProfileDesc->minApiVersion)) { - const uint32_t version_min_major = VK_API_VERSION_MAJOR(pProfileDesc->minApiVersion); - const uint32_t version_min_minor = VK_API_VERSION_MINOR(pProfileDesc->minApiVersion); - const uint32_t version_min_patch = VK_API_VERSION_PATCH(pProfileDesc->minApiVersion); - - const uint32_t version_major = VK_API_VERSION_MAJOR(api_version); - const uint32_t version_minor = VK_API_VERSION_MINOR(api_version); - const uint32_t version_patch = VK_API_VERSION_PATCH(api_version); - VP_DEBUG_MSGF("Unsupported Profile API version %u.%u.%u on a Vulkan system with version %u.%u.%u", version_min_major, version_min_minor, version_min_patch, version_major, version_minor, version_patch); - *pSupported = VK_FALSE; unsupportedBlocks.push_back(block); } @@ -10299,25 +11003,38 @@ VPAPI_ATTR VkResult vpGetInstanceProfileSupportSingleProfile( enum structure_type { STRUCTURE_FEATURE = 0, STRUCTURE_PROPERTY, + STRUCTURE_QUEUE_FAMILY, STRUCTURE_FORMAT }; -VPAPI_ATTR VkResult vpGetProfileStructureTypes(const VpProfileProperties *pProfile, const char* pBlockName, structure_type type, uint32_t *pStructureTypeCount, VkStructureType *pStructureTypes) { +VPAPI_ATTR VkResult vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + structure_type type, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; std::vector<VkStructureType> results; - const std::vector<VpProfileProperties>& profiles = detail::GatherProfiles(*pProfile); + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile); - for (std::size_t profile_index = 0, profile_count = profiles.size(); profile_index < profile_count; ++profile_index) { - const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(profiles[profile_index].profileName); + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { - const detail::VpCapabilitiesDesc& capabilities = profile_desc->pRequiredCapabilities[capability_index]; + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; - for (uint32_t variant_index = 0; variant_index < capabilities.variantCount; ++variant_index) { - const detail::VpVariantDesc& variant = capabilities.pVariants[variant_index]; + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; if (pBlockName != nullptr) { if (strcmp(variant.blockName, pBlockName) != 0) { continue; @@ -10338,16 +11055,20 @@ VPAPI_ATTR VkResult vpGetProfileStructureTypes(const VpProfileProperties *pProfi count = variant.propertyStructTypeCount; data = variant.pPropertyStructTypes; break; + case STRUCTURE_QUEUE_FAMILY: + count = variant.queueFamilyStructTypeCount; + data = variant.pQueueFamilyStructTypes; + break; case STRUCTURE_FORMAT: count = variant.formatStructTypeCount; data = variant.pFormatStructTypes; break; } - for (uint32_t i = 0; i < count; ++i) { - const VkStructureType type = data[i]; - if (std::find(results.begin(), results.end(), type) == std::end(results)) { - results.push_back(type); + for (uint32_t type_index = 0; type_index < count; ++type_index) { + const VkStructureType dataType = data[type_index]; + if (std::find(results.begin(), results.end(), dataType) == std::end(results)) { + results.push_back(dataType); } } } @@ -10379,22 +11100,36 @@ enum ExtensionType { EXTENSION_DEVICE, }; -VPAPI_ATTR VkResult vpGetProfileExtensionProperties(const VpProfileProperties *pProfile, const char* pBlockName, ExtensionType type, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) { +VPAPI_ATTR VkResult vpGetProfileExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + ExtensionType type, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; std::vector<VkExtensionProperties> results; - const std::vector<VpProfileProperties>& profiles = detail::GatherProfiles(*pProfile, pBlockName); + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile, pBlockName); - for (std::size_t profile_index = 0, profile_count = profiles.size(); profile_index < profile_count; ++profile_index) { - const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(profiles[profile_index].profileName); - if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) { + return VK_ERROR_UNKNOWN; + } for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { - const detail::VpCapabilitiesDesc& capabilities = profile_desc->pRequiredCapabilities[capability_index]; + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; - for (uint32_t variant_index = 0; variant_index < capabilities.variantCount; ++variant_index) { - const detail::VpVariantDesc& variant = capabilities.pVariants[variant_index]; + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; if (pBlockName != nullptr) { if (strcmp(variant.blockName, pBlockName) != 0) { continue; @@ -10405,19 +11140,19 @@ VPAPI_ATTR VkResult vpGetProfileExtensionProperties(const VpProfileProperties *p switch (type) { default: case EXTENSION_INSTANCE: - for (uint32_t i = 0; i < variant.instanceExtensionCount; ++i) { - if (detail::HasExtension(results, variant.pInstanceExtensions[i])) { + for (uint32_t ext_index = 0; ext_index < variant.instanceExtensionCount; ++ext_index) { + if (detail::HasExtension(results, variant.pInstanceExtensions[ext_index])) { continue; } - results.push_back(variant.pInstanceExtensions[i]); + results.push_back(variant.pInstanceExtensions[ext_index]); } break; case EXTENSION_DEVICE: - for (uint32_t i = 0; i < variant.deviceExtensionCount; ++i) { - if (detail::HasExtension(results, variant.pDeviceExtensions[i])) { + for (uint32_t ext_index = 0; ext_index < variant.deviceExtensionCount; ++ext_index) { + if (detail::HasExtension(results, variant.pDeviceExtensions[ext_index])) { continue; } - results.push_back(variant.pDeviceExtensions[i]); + results.push_back(variant.pDeviceExtensions[ext_index]); } break; } @@ -10443,9 +11178,244 @@ VPAPI_ATTR VkResult vpGetProfileExtensionProperties(const VpProfileProperties *p return result; } +VPAPI_ATTR VkResult vpGetProfileVideoProfileDesc( + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + const detail::VpVideoProfileDesc** ppVideoProfileDesc) { + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + uint32_t curr_base_video_profile_index = 0; + + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (videoProfileIndex < curr_base_video_profile_index + variant.videoProfileCount) { + *ppVideoProfileDesc = &variant.pVideoProfiles[videoProfileIndex - curr_base_video_profile_index]; + return result; + } else { + curr_base_video_profile_index += variant.videoProfileCount; + } + } + } + } + + *ppVideoProfileDesc = nullptr; + return VK_ERROR_UNKNOWN; +} + } // namespace detail -VPAPI_ATTR VkResult vpGetProfiles(uint32_t *pPropertyCount, VpProfileProperties *pProperties) { +struct VpCapabilities_T : public VpVulkanFunctions { + bool singleton = false; + uint32_t apiVersion = VK_API_VERSION_1_0; + + static VpCapabilities_T& Get() { + static VpCapabilities_T instance; + VpCapabilitiesCreateInfo createInfo{}; + createInfo.flags = VP_PROFILE_CREATE_STATIC_BIT; + instance.init(&createInfo); + instance.singleton = true; + return instance; + } + + VpCapabilities_T() { + this->GetInstanceProcAddr = nullptr; + this->GetDeviceProcAddr = nullptr; + this->EnumerateInstanceVersion = nullptr; + this->EnumerateInstanceExtensionProperties = nullptr; + this->EnumerateDeviceExtensionProperties = nullptr; + this->GetPhysicalDeviceFeatures2 = nullptr; + this->GetPhysicalDeviceProperties2 = nullptr; + this->GetPhysicalDeviceFormatProperties2 = nullptr; + this->GetPhysicalDeviceQueueFamilyProperties2 = nullptr; + this->CreateInstance = nullptr; + this->CreateDevice = nullptr; + } + + VkResult init(const VpCapabilitiesCreateInfo* pCreateInfo) { + assert(pCreateInfo != nullptr); + + return ImportVulkanFunctions(pCreateInfo); + } + + VkResult ImportVulkanFunctions(const VpCapabilitiesCreateInfo* pCreateInfo) { + if (pCreateInfo->flags & VP_PROFILE_CREATE_STATIC_BIT) { + ImportVulkanFunctions_Static(); + } + + if (pCreateInfo->pVulkanFunctions != nullptr) { + ImportVulkanFunctions_Custom((VpVulkanFunctions*)pCreateInfo->pVulkanFunctions); + } +/* + if (pCreateInfo->flags & VP_PROFILE_CREATE_DYNAMIC_BIT) { + ImportVulkanFunctions_Dynamic(); + } +*/ + return ValidateVulkanFunctions(); + } + + void ImportVulkanFunctions_Static() { + // Vulkan 1.1 + this->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)vkGetInstanceProcAddr; + this->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)vkGetDeviceProcAddr; + + this->EnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion)vkEnumerateInstanceVersion; + this->EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)vkEnumerateInstanceExtensionProperties; + this->EnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)vkEnumerateDeviceExtensionProperties; + + this->GetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2)vkGetPhysicalDeviceFeatures2; + this->GetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2)vkGetPhysicalDeviceProperties2; + this->GetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2)vkGetPhysicalDeviceFormatProperties2; + this->GetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2)vkGetPhysicalDeviceQueueFamilyProperties2; + + this->CreateInstance = (PFN_vkCreateInstance)vkCreateInstance; + this->CreateDevice = (PFN_vkCreateDevice)vkCreateDevice; + } + + void ImportVulkanFunctions_Custom(VpVulkanFunctions* pFunctions) { + #define VP_COPY_IF_NOT_NULL(funcName) if(pFunctions->funcName != nullptr) this->funcName = pFunctions->funcName; + + VP_COPY_IF_NOT_NULL(GetInstanceProcAddr); + VP_COPY_IF_NOT_NULL(GetDeviceProcAddr); + + VP_COPY_IF_NOT_NULL(EnumerateInstanceVersion); + VP_COPY_IF_NOT_NULL(EnumerateInstanceExtensionProperties); + VP_COPY_IF_NOT_NULL(EnumerateDeviceExtensionProperties); + + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceFeatures2); + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceProperties2); + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceFormatProperties2); + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceQueueFamilyProperties2); + + VP_COPY_IF_NOT_NULL(CreateInstance); + VP_COPY_IF_NOT_NULL(CreateDevice); + #undef VP_COPY_IF_NOT_NULL + } +/* + VkResult ImportVulkanFunctions_Dynamic() { + // To use VP_PROFILE_CREATE_DYNAMIC_BIT you have to pass VpVulkanFunctions::vkGetInstanceProcAddr and vkGetDeviceProcAddr as VpCapabilitiesCreateInfo::pVulkanFunctions. Other members can be null. + if (this->GetInstanceProcAddr == nullptr || this->GetDeviceProcAddr == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + #define VP_FETCH_INSTANCE_FUNC(memberName, functionNameString) if(this->memberName == nullptr) this->memberName = (PFN_vk##memberName)this->GetInstanceProcAddr(m_hInstance, functionNameString); + #define VP_FETCH_DEVICE_FUNC(memberName, functionNameString) if(this->memberName == nullptr) this->memberName = (PFN_vk##memberName)this->GetDeviceProcAddr(m_hDevice, functionNameString); + + VP_FETCH_INSTANCE_FUNC(GetInstanceProcAddr, "vkGetInstanceProcAddr"); + VP_FETCH_DEVICE_FUNC(GetDeviceProcAddr, "vkGetDeviceProcAddr"); + + VP_FETCH_INSTANCE_FUNC(EnumerateInstanceVersion, "vkEnumerateInstanceVersion"); + VP_FETCH_INSTANCE_FUNC(EnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties"); + VP_FETCH_DEVICE_FUNC(EnumerateDeviceExtensionProperties, "vkEnumerateDeviceExtensionProperties"); + + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceFeatures2, "vkGetPhysicalDeviceFeatures2"); + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceProperties2, "vkGetPhysicalDeviceProperties2"); + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceFormatProperties2, "vkGetPhysicalDeviceFormatProperties2"); + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceQueueFamilyProperties2, "vkGetPhysicalDeviceQueueFamilyProperties2"); + + VP_FETCH_INSTANCE_FUNC(CreateInstance, "vkCreateInstance"); + VP_FETCH_DEVICE_FUNC(CreateDevice, "vkCreateDevice"); + #undef VP_FETCH_DEVICE_FUNC + #undef VP_FETCH_INSTANCE_FUNC + } +*/ + VkResult ValidateVulkanFunctions() { + if (this->GetInstanceProcAddr == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->GetDeviceProcAddr == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->EnumerateInstanceVersion == nullptr && apiVersion >= VK_API_VERSION_1_1) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->EnumerateInstanceExtensionProperties == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->EnumerateDeviceExtensionProperties == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->GetPhysicalDeviceFeatures2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->GetPhysicalDeviceProperties2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->GetPhysicalDeviceFormatProperties2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->GetPhysicalDeviceQueueFamilyProperties2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->CreateInstance == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->CreateDevice == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + return VK_SUCCESS; + } +}; + +VPAPI_ATTR VkResult vpCreateCapabilities( + const VpCapabilitiesCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VpCapabilities* pCapabilities) { + (void)pAllocator; + + VpCapabilities_T* capabilities = new VpCapabilities_T(); + VkResult result = capabilities->init(pCreateInfo); + *pCapabilities = capabilities; + + return result; +} + +/// Destroys allocator object. +VPAPI_ATTR void vpDestroyCapabilities( + VpCapabilities capabilities, + const VkAllocationCallbacks* pAllocator) { + (void)pAllocator; + + delete capabilities; +} + +VPAPI_ATTR VkResult vpGetProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + uint32_t* pPropertyCount, + VpProfileProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + VkResult result = VK_SUCCESS; if (pProperties == nullptr) { @@ -10456,83 +11426,128 @@ VPAPI_ATTR VkResult vpGetProfiles(uint32_t *pPropertyCount, VpProfileProperties } else { *pPropertyCount = detail::profileCount; } - for (uint32_t i = 0; i < *pPropertyCount; ++i) { - pProperties[i] = detail::profiles[i].props; + for (uint32_t property_index = 0; property_index < *pPropertyCount; ++property_index) { + pProperties[property_index] = detail::profiles[property_index].props; } } return result; } -VPAPI_ATTR VkResult vpGetProfileRequiredProfiles(const VpProfileProperties *pProfile, uint32_t *pPropertyCount, VpProfileProperties *pProperties) { +VPAPI_ATTR VkResult vpGetProfileRequiredProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + VkResult result = VK_SUCCESS; - const detail::VpProfileDesc* pDesc = detail::vpGetProfileDesc(pProfile->profileName); - if (pDesc == nullptr) return VK_ERROR_UNKNOWN; + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(pProfile->profileName); + if (desc == nullptr) { + return VK_ERROR_UNKNOWN; + } if (pProperties == nullptr) { - *pPropertyCount = pDesc->requiredProfileCount; + *pPropertyCount = desc->requiredProfileCount; } else { - if (*pPropertyCount < pDesc->requiredProfileCount) { + if (*pPropertyCount < desc->requiredProfileCount) { result = VK_INCOMPLETE; } else { - *pPropertyCount = pDesc->requiredProfileCount; + *pPropertyCount = desc->requiredProfileCount; } - for (uint32_t i = 0; i < *pPropertyCount; ++i) { - pProperties[i] = pDesc->pRequiredProfiles[i]; + for (uint32_t property_index = 0; property_index < *pPropertyCount; ++property_index) { + pProperties[property_index] = desc->pRequiredProfiles[property_index]; } } return result; } -VPAPI_ATTR uint32_t vpGetProfileAPIVersion(const VpProfileProperties* pProfile) { - const std::vector<VpProfileProperties>& profiles = detail::GatherProfiles(*pProfile, nullptr); +VPAPI_ATTR uint32_t vpGetProfileAPIVersion( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile, nullptr); uint32_t major = 0; uint32_t minor = 0; uint32_t patch = 0; - for (std::size_t i = 0, n = profiles.size(); i < n; ++i) { - const detail::VpProfileDesc* pDesc = detail::vpGetProfileDesc(profiles[i].profileName); - if (pDesc == nullptr) return 0; + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (desc == nullptr) { + return 0; + } - major = std::max<uint32_t>(major, VK_API_VERSION_MAJOR(pDesc->minApiVersion)); - minor = std::max<uint32_t>(minor, VK_API_VERSION_MINOR(pDesc->minApiVersion)); - patch = std::max<uint32_t>(patch, VK_API_VERSION_PATCH(pDesc->minApiVersion)); + major = std::max<uint32_t>(major, VK_API_VERSION_MAJOR(desc->minApiVersion)); + minor = std::max<uint32_t>(minor, VK_API_VERSION_MINOR(desc->minApiVersion)); + patch = std::max<uint32_t>(patch, VK_API_VERSION_PATCH(desc->minApiVersion)); } return VK_MAKE_API_VERSION(0, major, minor, patch); } -VPAPI_ATTR VkResult vpGetProfileFallbacks(const VpProfileProperties *pProfile, uint32_t *pPropertyCount, VpProfileProperties *pProperties) { +VPAPI_ATTR VkResult vpGetProfileFallbacks( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + VkResult result = VK_SUCCESS; - const detail::VpProfileDesc* pDesc = detail::vpGetProfileDesc(pProfile->profileName); - if (pDesc == nullptr) return VK_ERROR_UNKNOWN; + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(pProfile->profileName); + if (desc == nullptr) { + return VK_ERROR_UNKNOWN; + } if (pProperties == nullptr) { - *pPropertyCount = pDesc->fallbackCount; + *pPropertyCount = desc->fallbackCount; } else { - if (*pPropertyCount < pDesc->fallbackCount) { + if (*pPropertyCount < desc->fallbackCount) { result = VK_INCOMPLETE; } else { - *pPropertyCount = pDesc->fallbackCount; + *pPropertyCount = desc->fallbackCount; } for (uint32_t i = 0; i < *pPropertyCount; ++i) { - pProperties[i] = pDesc->pFallbacks[i]; + pProperties[i] = desc->pFallbacks[i]; } } return result; } -VPAPI_ATTR VkResult vpHasMultipleVariantsProfile(const VpProfileProperties *pProfile, VkBool32 *pHasMultipleVariants) { - const std::vector<VpProfileProperties>& profiles = detail::GatherProfiles(*pProfile, nullptr); +VPAPI_ATTR VkResult vpHasMultipleVariantsProfile( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + VkBool32* pHasMultipleVariants) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile, nullptr); - for (std::size_t profile_index = 0, profile_count = profiles.size(); profile_index < profile_count; ++profile_index) { - const detail::VpProfileDesc* pDesc = detail::vpGetProfileDesc(profiles[profile_index].profileName); - if (pDesc == nullptr) return VK_ERROR_UNKNOWN; + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (desc == nullptr) { + return VK_ERROR_UNKNOWN; + } - for (uint32_t capabilities_index = 0, n = pDesc->requiredCapabilityCount; capabilities_index < n; ++capabilities_index) { - if (pDesc->pRequiredCapabilities[capabilities_index].variantCount > 1) { + for (uint32_t caps_index = 0, caps_count = desc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + if (desc->pRequiredCapabilities[caps_index].variantCount > 1) { *pHasMultipleVariants = VK_TRUE; return VK_SUCCESS; } @@ -10543,22 +11558,37 @@ VPAPI_ATTR VkResult vpHasMultipleVariantsProfile(const VpProfileProperties *pPro return VK_SUCCESS; } -VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport(const char *pLayerName, const VpProfileProperties *pProfile, VkBool32 *pSupported, uint32_t *pPropertyCount, VpBlockProperties* pProperties) { +VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + uint32_t* pPropertyCount, + VpBlockProperties* pProperties) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + VkResult result = VK_SUCCESS; - uint32_t api_version = VK_MAKE_API_VERSION(0, 1, 0, 0); - static PFN_vkEnumerateInstanceVersion pfnEnumerateInstanceVersion = - (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion"); + uint32_t api_version = VK_API_VERSION_1_0; + PFN_vkEnumerateInstanceVersion pfnEnumerateInstanceVersion = vp.singleton ? + (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion") : vp.EnumerateInstanceVersion; if (pfnEnumerateInstanceVersion != nullptr) { result = pfnEnumerateInstanceVersion(&api_version); if (result != VK_SUCCESS) { *pSupported = VK_FALSE; return result; - } + } /* else { + } */ } uint32_t supported_instance_extension_count = 0; - result = vkEnumerateInstanceExtensionProperties(pLayerName, &supported_instance_extension_count, nullptr); + result = vp.EnumerateInstanceExtensionProperties(pLayerName, &supported_instance_extension_count, nullptr); if (result != VK_SUCCESS) { *pSupported = VK_FALSE; return result; @@ -10567,7 +11597,7 @@ VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport(const char *pLayerName, if (supported_instance_extension_count > 0) { supported_instance_extensions.resize(supported_instance_extension_count); } - result = vkEnumerateInstanceExtensionProperties(pLayerName, &supported_instance_extension_count, supported_instance_extensions.data()); + result = vp.EnumerateInstanceExtensionProperties(pLayerName, &supported_instance_extension_count, supported_instance_extensions.data()); if (result != VK_SUCCESS) { *pSupported = VK_FALSE; return result; @@ -10578,14 +11608,13 @@ VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport(const char *pLayerName, // We require VK_KHR_get_physical_device_properties2 if we are on Vulkan 1.0 if (api_version < VK_API_VERSION_1_1) { bool foundGPDP2 = false; - for (size_t i = 0; i < supported_instance_extensions.size(); ++i) { - if (strcmp(supported_instance_extensions[i].extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { + for (size_t ext_index = 0, ext_count = supported_instance_extensions.size(); ext_index < ext_count; ++ext_index) { + if (strcmp(supported_instance_extensions[ext_index].extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { foundGPDP2 = true; break; } } if (!foundGPDP2) { - VP_DEBUG_MSG("Unsupported mandatory extension VK_KHR_get_physical_device_properties2 on Vulkan 1.0"); supported = VK_FALSE; } } @@ -10601,9 +11630,9 @@ VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport(const char *pLayerName, *pSupported = supported; return result; } - - for (std::size_t i = 0; i < pProfileDesc->requiredProfileCount; ++i) { - result = detail::vpGetInstanceProfileSupportSingleProfile(0, supported_instance_extensions, &pProfileDesc->pRequiredProfiles[i], &supported, supported_blocks, unsupported_blocks); + + for (std::size_t required_profile_index = 0; required_profile_index < pProfileDesc->requiredProfileCount; ++required_profile_index) { + result = detail::vpGetInstanceProfileSupportSingleProfile(0, supported_instance_extensions, &pProfileDesc->pRequiredProfiles[required_profile_index], &supported, supported_blocks, unsupported_blocks); if (result != VK_SUCCESS) { *pSupported = supported; return result; @@ -10620,8 +11649,8 @@ VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport(const char *pLayerName, } else { *pPropertyCount = static_cast<uint32_t>(blocks.size()); } - for (uint32_t i = 0, n = static_cast<uint32_t>(blocks.size()); i < n; ++i) { - pProperties[i] = blocks[i]; + for (uint32_t block_index = 0, block_count = static_cast<uint32_t>(blocks.size()); block_index < block_count; ++block_index) { + pProperties[block_index] = blocks[block_index]; } } @@ -10629,16 +11658,37 @@ VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport(const char *pLayerName, return result; } -VPAPI_ATTR VkResult vpGetInstanceProfileSupport(const char *pLayerName, const VpProfileProperties *pProfile, VkBool32 *pSupported) { +VPAPI_ATTR VkResult vpGetInstanceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported) { uint32_t count = 0; - return vpGetInstanceProfileVariantsSupport(pLayerName, pProfile, pSupported, &count, nullptr); + + return vpGetInstanceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pLayerName, pProfile, pSupported, &count, nullptr); } +VPAPI_ATTR VkResult vpCreateInstance( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT -VPAPI_ATTR VkResult vpCreateInstance(const VpInstanceCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { if (pCreateInfo == nullptr || pInstance == nullptr) { - return vkCreateInstance(pCreateInfo == nullptr ? nullptr : pCreateInfo->pCreateInfo, pAllocator, pInstance); + return vp.CreateInstance(pCreateInfo == nullptr ? nullptr : pCreateInfo->pCreateInfo, pAllocator, pInstance); } const std::vector<VpBlockProperties>& blocks = detail::GatherBlocks( @@ -10646,22 +11696,24 @@ VPAPI_ATTR VkResult vpCreateInstance(const VpInstanceCreateInfo *pCreateInfo, pCreateInfo->enabledProfileBlockCount, pCreateInfo->pEnabledProfileBlocks); std::vector<const char*> extensions; - for (std::uint32_t i = 0, n = pCreateInfo->pCreateInfo->enabledExtensionCount; i < n; ++i) { - extensions.push_back(pCreateInfo->pCreateInfo->ppEnabledExtensionNames[i]); + for (std::uint32_t ext_index = 0, ext_count = pCreateInfo->pCreateInfo->enabledExtensionCount; ext_index < ext_count; ++ext_index) { + extensions.push_back(pCreateInfo->pCreateInfo->ppEnabledExtensionNames[ext_index]); } - for (std::size_t i = 0, n = blocks.size(); i < n; ++i) { - const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(blocks[i].profiles.profileName); - if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + for (std::size_t block_index = 0, block_count = blocks.size(); block_index < block_count; ++block_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(blocks[block_index].profiles.profileName); + if (profile_desc == nullptr) { + return VK_ERROR_UNKNOWN; + } - for (std::size_t j = 0, p = pProfileDesc->requiredCapabilityCount; j < p; ++j) { - const detail::VpCapabilitiesDesc* pCapsDesc = &pProfileDesc->pRequiredCapabilities[j]; + for (std::size_t caps_index = 0, caps_count = profile_desc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + const detail::VpCapabilitiesDesc* caps_desc = &profile_desc->pRequiredCapabilities[caps_index]; - for (std::size_t v = 0, q = pCapsDesc->variantCount; v < q; ++v) { - const detail::VpVariantDesc* variant = &pCapsDesc->pVariants[v]; + for (std::size_t variant_index = 0, variant_count = caps_desc->variantCount; variant_index < variant_count; ++variant_index) { + const detail::VpVariantDesc* variant = &caps_desc->pVariants[variant_index]; - if (strcmp(blocks[i].blockName, "") != 0) { - if (strcmp(variant->blockName, blocks[i].blockName) != 0) { + if (strcmp(blocks[block_index].blockName, "") != 0) { + if (strcmp(variant->blockName, blocks[block_index].blockName) != 0) { continue; } } @@ -10675,7 +11727,11 @@ VPAPI_ATTR VkResult vpCreateInstance(const VpInstanceCreateInfo *pCreateInfo, if (pCreateInfo->pCreateInfo->pApplicationInfo != nullptr) { appInfo = *pCreateInfo->pCreateInfo->pApplicationInfo; } else if (!blocks.empty()) { - appInfo.apiVersion = vpGetProfileAPIVersion(&blocks[0].profiles); + appInfo.apiVersion = vpGetProfileAPIVersion( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + &blocks[0].profiles); } VkInstanceCreateInfo createInfo = *pCreateInfo->pCreateInfo; @@ -10684,8 +11740,8 @@ VPAPI_ATTR VkResult vpCreateInstance(const VpInstanceCreateInfo *pCreateInfo, // Need to include VK_KHR_get_physical_device_properties2 if we are on Vulkan 1.0 if (createInfo.pApplicationInfo->apiVersion < VK_API_VERSION_1_1) { bool foundGPDP2 = false; - for (size_t i = 0; i < extensions.size(); ++i) { - if (strcmp(extensions[i], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { + for (size_t ext_index = 0, ext_count = extensions.size(); ext_index < ext_count; ++ext_index) { + if (strcmp(extensions[ext_index], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { foundGPDP2 = true; break; } @@ -10697,8 +11753,8 @@ VPAPI_ATTR VkResult vpCreateInstance(const VpInstanceCreateInfo *pCreateInfo, #ifdef __APPLE__ bool has_portability_ext = false; - for (std::size_t i = 0, n = extensions.size(); i < n; ++i) { - if (strcmp(extensions[i], VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0) { + for (std::size_t ext_index = 0, ext_count = extensions.size(); ext_index < ext_count; ++ext_index) { + if (strcmp(extensions[ext_index], VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0) { has_portability_ext = true; break; } @@ -10716,15 +11772,29 @@ VPAPI_ATTR VkResult vpCreateInstance(const VpInstanceCreateInfo *pCreateInfo, createInfo.ppEnabledExtensionNames = extensions.data(); } - return vkCreateInstance(&createInfo, pAllocator, pInstance); + return vp.CreateInstance(&createInfo, pAllocator, pInstance); } -VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instance, VkPhysicalDevice physicalDevice, - const VpProfileProperties *pProfile, VkBool32 *pSupported, uint32_t *pPropertyCount, VpBlockProperties* pProperties) { +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties *pProfile, + VkBool32 *pSupported, + uint32_t *pPropertyCount, + VpBlockProperties* pProperties) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + VkResult result = VK_SUCCESS; uint32_t supported_device_extension_count = 0; - result = vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &supported_device_extension_count, nullptr); + result = vp.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &supported_device_extension_count, nullptr); if (result != VK_SUCCESS) { return result; } @@ -10732,7 +11802,7 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc if (supported_device_extension_count > 0) { supported_device_extensions.resize(supported_device_extension_count); } - result = vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &supported_device_extension_count, supported_device_extensions.data()); + result = vp.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &supported_device_extension_count, supported_device_extensions.data()); if (result != VK_SUCCESS) { return result; } @@ -10742,8 +11812,12 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc supported_device_extensions.resize(supported_device_extension_count); } - const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(pProfile->profileName); - if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + { + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(pProfile->profileName); + if (pProfileDesc == nullptr) { + return VK_ERROR_UNKNOWN; + } + } struct GPDP2EntryPoints { PFN_vkGetPhysicalDeviceFeatures2KHR pfnGetPhysicalDeviceFeatures2; @@ -10752,6 +11826,18 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR pfnGetPhysicalDeviceQueueFamilyProperties2; }; +#ifdef VK_KHR_video_queue + struct VideoInfo { + PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR pfnGetPhysicalDeviceVideoCapabilitiesKHR; + PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR pfnGetPhysicalDeviceVideoFormatPropertiesKHR; + const detail::VpVideoProfileDesc* pProfileDesc; + VkVideoProfileInfoKHR profileInfo; + VkPhysicalDeviceVideoFormatInfoKHR formatInfo; + bool supportedProfile; + uint32_t matchingProfiles; + }; +#endif // VK_KHR_video_queue + std::vector<VpBlockProperties> supported_blocks; std::vector<VpBlockProperties> unsupported_blocks; @@ -10761,21 +11847,32 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc std::vector<VpBlockProperties>& unsupported_blocks; const detail::VpVariantDesc* variant; GPDP2EntryPoints gpdp2; +#ifdef VK_KHR_video_queue + VideoInfo video; +#endif // VK_KHR_video_queue uint32_t index; - uint32_t count; detail::PFN_vpStructChainerCb pfnCb; bool supported; } userData{physicalDevice, supported_blocks, unsupported_blocks}; + if (!vp.singleton) { + userData.gpdp2.pfnGetPhysicalDeviceFeatures2 = vp.GetPhysicalDeviceFeatures2; + userData.gpdp2.pfnGetPhysicalDeviceProperties2 = vp.GetPhysicalDeviceProperties2; + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 = vp.GetPhysicalDeviceFormatProperties2; + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 = vp.GetPhysicalDeviceQueueFamilyProperties2; + } + // Attempt to load core versions of the GPDP2 entry points - userData.gpdp2.pfnGetPhysicalDeviceFeatures2 = - (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2"); - userData.gpdp2.pfnGetPhysicalDeviceProperties2 = - (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2"); - userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 = - (PFN_vkGetPhysicalDeviceFormatProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2"); - userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 = - (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2"); + if (userData.gpdp2.pfnGetPhysicalDeviceFeatures2 == nullptr) { + userData.gpdp2.pfnGetPhysicalDeviceFeatures2 = + (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2"); + userData.gpdp2.pfnGetPhysicalDeviceProperties2 = + (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2"); + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 = + (PFN_vkGetPhysicalDeviceFormatProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2"); + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 = + (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2"); + } // If not successful, try to load KHR variant if (userData.gpdp2.pfnGetPhysicalDeviceFeatures2 == nullptr) { @@ -10796,36 +11893,44 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc return VK_ERROR_EXTENSION_NOT_PRESENT; } - VP_DEBUG_MSGF("Checking device support for profile %s (%s). You may find the details of the capabilities of this device on https://vulkan.gpuinfo.org/", pProfile->profileName, detail::vpGetDeviceAndDriverInfoString(physicalDevice, userData.gpdp2.pfnGetPhysicalDeviceProperties2).c_str()); +#ifdef VK_KHR_video_queue + PFN_vkGetInstanceProcAddr gipa = vp.singleton ? vkGetInstanceProcAddr : vp.GetInstanceProcAddr; + userData.video.pfnGetPhysicalDeviceVideoCapabilitiesKHR = + (PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)gipa(instance, "vkGetPhysicalDeviceVideoCapabilitiesKHR"); + userData.video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR = + (PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)gipa(instance, "vkGetPhysicalDeviceVideoFormatPropertiesKHR"); +#endif // VK_KHR_video_queue bool supported = true; - const std::vector<VpProfileProperties>& profiles = detail::GatherProfiles(*pProfile); + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile); - for (std::size_t i = 0, n = profiles.size(); i < n; ++i) { - const char* profile_name = profiles[i].profileName; + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const char* profile_name = gathered_profiles[profile_index].profileName; - const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(profile_name); - if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(profile_name); + if (profile_desc == nullptr) { + return VK_ERROR_UNKNOWN; + } bool supported_profile = true; - - if (pProfileDesc->props.specVersion < pProfile->specVersion) { + if (profile_desc->props.specVersion < gathered_profiles[profile_index].specVersion) { supported_profile = false; } - VpBlockProperties block{profiles[i], pProfileDesc->minApiVersion}; + VpBlockProperties block{gathered_profiles[profile_index], profile_desc->minApiVersion}; - VkPhysicalDeviceProperties props{}; - vkGetPhysicalDeviceProperties(physicalDevice, &props); - if (!detail::vpCheckVersion(props.apiVersion, pProfileDesc->minApiVersion)) { - VP_DEBUG_MSGF("Unsupported API version: %u.%u.%u", VK_API_VERSION_MAJOR(pProfileDesc->minApiVersion), VK_API_VERSION_MINOR(pProfileDesc->minApiVersion), VK_API_VERSION_PATCH(pProfileDesc->minApiVersion)); - supported_profile = false; + { + VkPhysicalDeviceProperties2KHR properties2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR }; + userData.gpdp2.pfnGetPhysicalDeviceProperties2(physicalDevice, &properties2); + if (!detail::vpCheckVersion(properties2.properties.apiVersion, profile_desc->minApiVersion)) { + supported_profile = false; + } } - for (uint32_t required_capability_index = 0; required_capability_index < pProfileDesc->requiredCapabilityCount; ++required_capability_index) { - const detail::VpCapabilitiesDesc* required_capabilities = &pProfileDesc->pRequiredCapabilities[required_capability_index]; + for (uint32_t required_capability_index = 0; required_capability_index < profile_desc->requiredCapabilityCount; ++required_capability_index) { + const detail::VpCapabilitiesDesc* required_capabilities = &profile_desc->pRequiredCapabilities[required_capability_index]; bool supported_block = false; @@ -10834,8 +11939,8 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc bool supported_variant = true; - for (uint32_t i = 0; i < variant_desc.deviceExtensionCount; ++i) { - const char *requested_extension = variant_desc.pDeviceExtensions[i].extensionName; + for (uint32_t ext_index = 0; ext_index < variant_desc.deviceExtensionCount; ++ext_index) { + const char *requested_extension = variant_desc.pDeviceExtensions[ext_index].extensionName; if (!detail::CheckExtension(supported_device_extensions.data(), supported_device_extensions.size(), requested_extension)) { supported_variant = false; } @@ -10848,8 +11953,10 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc static_cast<VkBaseOutStructure*>(static_cast<void*>(&features)), &userData, [](VkBaseOutStructure* p, void* pUser) { UserData* pUserData = static_cast<UserData*>(pUser); - pUserData->gpdp2.pfnGetPhysicalDeviceFeatures2(pUserData->physicalDevice, - static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p))); + pUserData->gpdp2.pfnGetPhysicalDeviceFeatures2( + pUserData->physicalDevice, + static_cast<VkPhysicalDeviceFeatures2KHR*>(static_cast<void*>(p))); + pUserData->supported = true; while (p != nullptr) { if (!pUserData->variant->feature.pfnComparator(p)) { @@ -10863,13 +11970,15 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc supported_variant = false; } - VkPhysicalDeviceProperties2KHR props{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR }; + VkPhysicalDeviceProperties2KHR device_properties2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR }; userData.variant->chainers.pfnProperty( - static_cast<VkBaseOutStructure*>(static_cast<void*>(&props)), &userData, + static_cast<VkBaseOutStructure*>(static_cast<void*>(&device_properties2)), &userData, [](VkBaseOutStructure* p, void* pUser) { UserData* pUserData = static_cast<UserData*>(pUser); - pUserData->gpdp2.pfnGetPhysicalDeviceProperties2(pUserData->physicalDevice, - static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p))); + pUserData->gpdp2.pfnGetPhysicalDeviceProperties2( + pUserData->physicalDevice, + static_cast<VkPhysicalDeviceProperties2KHR*>(static_cast<void*>(p))); + pUserData->supported = true; while (p != nullptr) { if (!pUserData->variant->property.pfnComparator(p)) { @@ -10883,15 +11992,56 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc supported_variant = false; } - for (uint32_t i = 0; i < userData.variant->formatCount && supported_variant; ++i) { - userData.index = i; - VkFormatProperties2KHR props{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR }; + if (userData.variant->queueFamilyCount > 0) { + uint32_t queue_family_count = 0; + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queue_family_count, nullptr); + std::vector<VkQueueFamilyProperties2KHR> queueFamilyProps(queue_family_count, { VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR }); + userData.variant->chainers.pfnQueueFamily( + queue_family_count, static_cast<VkBaseOutStructure*>(static_cast<void*>(queueFamilyProps.data())), &userData, + [](uint32_t queue_family_count, VkBaseOutStructure* pBaseArray, void* pUser) { + UserData* pUserData = static_cast<UserData*>(pUser); + VkQueueFamilyProperties2KHR* pArray = static_cast<VkQueueFamilyProperties2KHR*>(static_cast<void*>(pBaseArray)); + pUserData->gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2(pUserData->physicalDevice, &queue_family_count, pArray); + pUserData->supported = true; + for (uint32_t profile_qf_idx = 0; profile_qf_idx < pUserData->variant->queueFamilyCount; ++profile_qf_idx) { + bool found_matching = false; + for (uint32_t queue_family_index = 0; queue_family_index < queue_family_count; ++queue_family_index) { + bool this_matches = true; + VkBaseOutStructure* p = static_cast<VkBaseOutStructure*>(static_cast<void*>(&pArray[queue_family_index])); + while (p != nullptr) { + if (!pUserData->variant->pQueueFamilies[profile_qf_idx].pfnComparator(p)) { + this_matches = false; + } + p = p->pNext; + } + if (this_matches) { + found_matching = true; + break; + } + } + if (!found_matching) { + pUserData->supported = false; + break; + } + } + } + ); + if (!userData.supported) { + supported_variant = false; + } + } + + for (uint32_t format_index = 0; format_index < userData.variant->formatCount && supported_variant; ++format_index) { + userData.index = format_index; + VkFormatProperties2KHR format_properties2{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR }; userData.variant->chainers.pfnFormat( - static_cast<VkBaseOutStructure*>(static_cast<void*>(&props)), &userData, + static_cast<VkBaseOutStructure*>(static_cast<void*>(&format_properties2)), &userData, [](VkBaseOutStructure* p, void* pUser) { UserData* pUserData = static_cast<UserData*>(pUser); - pUserData->gpdp2.pfnGetPhysicalDeviceFormatProperties2(pUserData->physicalDevice, pUserData->variant->pFormats[pUserData->index].format, - static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p))); + pUserData->gpdp2.pfnGetPhysicalDeviceFormatProperties2( + pUserData->physicalDevice, + pUserData->variant->pFormats[pUserData->index].format, + static_cast<VkFormatProperties2KHR*>(static_cast<void*>(p))); pUserData->supported = true; while (p != nullptr) { if (!pUserData->variant->pFormats[pUserData->index].pfnComparator(p)) { @@ -10906,6 +12056,113 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc } } +#ifdef VK_KHR_video_queue + if (userData.variant->videoProfileCount > 0) { + VkVideoProfileListInfoKHR profile_list{ VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR }; + profile_list.profileCount = 1; + profile_list.pProfiles = &userData.video.profileInfo; + userData.video.formatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR; + userData.video.formatInfo.pNext = &profile_list; + + if (userData.video.pfnGetPhysicalDeviceVideoCapabilitiesKHR != nullptr && + userData.video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR != nullptr) { + for (uint32_t video_profile_index = 0; video_profile_index < userData.variant->videoProfileCount; ++video_profile_index) { + userData.video.profileInfo = VkVideoProfileInfoKHR{ VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR }; + userData.video.pProfileDesc = &userData.variant->pVideoProfiles[video_profile_index]; + userData.supported = true; + userData.video.matchingProfiles = 0; + + detail::vpForEachMatchingVideoProfiles(&userData.video.profileInfo, &userData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast<UserData*>(pUser); + while (p != nullptr) { + if (!pUserData->video.pProfileDesc->info.pfnComparator(p)) { + return; + } + p = p->pNext; + } + + pUserData->video.supportedProfile = true; + + VkVideoCapabilitiesKHR capabilities{ VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR }; + pUserData->video.pProfileDesc->chainers.pfnCapability( + static_cast<VkBaseOutStructure*>(static_cast<void*>(&capabilities)), pUserData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast<UserData*>(pUser); + VkResult result = pUserData->video.pfnGetPhysicalDeviceVideoCapabilitiesKHR( + pUserData->physicalDevice, + &pUserData->video.profileInfo, + static_cast<VkVideoCapabilitiesKHR*>(static_cast<void*>(p))); + if (result != VK_SUCCESS) { + pUserData->video.supportedProfile = false; + return; + } + while (p != nullptr) { + if (!pUserData->video.pProfileDesc->capability.pfnComparator(p)) { + pUserData->supported = false; + } + p = p->pNext; + } + } + ); + + if (pUserData->video.supportedProfile) { + pUserData->video.matchingProfiles++; + } else { + return; + } + + std::vector<VkVideoFormatPropertiesKHR> format_props; + for (uint32_t format_index = 0; format_index < pUserData->video.pProfileDesc->formatCount; ++format_index) { + pUserData->index = format_index; + { + VkVideoFormatPropertiesKHR tmp_props{ VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR }; + pUserData->video.pProfileDesc->pFormats[format_index].pfnFiller(static_cast<VkBaseOutStructure*>(static_cast<void*>(&tmp_props))); + pUserData->video.formatInfo.imageUsage = tmp_props.imageUsageFlags; + } + + uint32_t format_count = 0; + pUserData->video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR(pUserData->physicalDevice, &pUserData->video.formatInfo, &format_count, nullptr); + format_props.resize(format_count, { VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR }); + pUserData->video.pProfileDesc->chainers.pfnFormat( + format_count, static_cast<VkBaseOutStructure*>(static_cast<void*>(format_props.data())), pUserData, + [](uint32_t format_count, VkBaseOutStructure* pBaseArray, void* pUser) { + UserData* pUserData = static_cast<UserData*>(pUser); + VkVideoFormatPropertiesKHR* pArray = static_cast<VkVideoFormatPropertiesKHR*>(static_cast<void*>(pBaseArray)); + pUserData->video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR(pUserData->physicalDevice, &pUserData->video.formatInfo, &format_count, pArray); + bool found_matching = false; + for (uint32_t i = 0; i < format_count; ++i) { + bool this_matches = true; + VkBaseOutStructure* p = static_cast<VkBaseOutStructure*>(static_cast<void*>(&pArray[i])); + while (p != nullptr) { + if (!pUserData->video.pProfileDesc->pFormats[pUserData->index].pfnComparator(p)) { + this_matches = false; + } + p = p->pNext; + } + if (this_matches) { + found_matching = true; + break; + } + } + if (!found_matching) { + pUserData->supported = false; + } + } + ); + } + } + ); + if (!userData.supported || userData.video.matchingProfiles == 0) { + supported_variant = false; + } + } + } else { + supported_variant = false; + } + } +#endif // VK_KHR_video_queue + memcpy(block.blockName, variant_desc.blockName, VP_MAX_PROFILE_NAME_SIZE * sizeof(char)); if (supported_variant) { supported_blocks.push_back(block); @@ -10945,16 +12202,39 @@ VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instanc return VK_SUCCESS; } -VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileSupport(VkInstance instance, VkPhysicalDevice physicalDevice, - const VpProfileProperties *pProfile, VkBool32 *pSupported) { +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties* pProfile, + VkBool32 *pSupported) { uint32_t count = 0; - return vpGetPhysicalDeviceProfileVariantsSupport(instance, physicalDevice, pProfile, pSupported, &count, nullptr); + + return vpGetPhysicalDeviceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + instance, physicalDevice, pProfile, pSupported, &count, nullptr); } -VPAPI_ATTR VkResult vpCreateDevice(VkPhysicalDevice physicalDevice, const VpDeviceCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { +VPAPI_ATTR VkResult vpCreateDevice( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkPhysicalDevice physicalDevice, + const VpDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + if (physicalDevice == VK_NULL_HANDLE || pCreateInfo == nullptr || pDevice == nullptr) { - return vkCreateDevice(physicalDevice, pCreateInfo == nullptr ? nullptr : pCreateInfo->pCreateInfo, pAllocator, pDevice); + return vp.CreateDevice(physicalDevice, pCreateInfo == nullptr ? nullptr : pCreateInfo->pCreateInfo, pAllocator, pDevice); } const std::vector<VpBlockProperties>& blocks = detail::GatherBlocks( @@ -10965,28 +12245,28 @@ VPAPI_ATTR VkResult vpCreateDevice(VkPhysicalDevice physicalDevice, const VpDevi std::vector<VkStructureType> structureTypes; std::vector<const char*> extensions; - for (std::uint32_t i = 0, n = pCreateInfo->pCreateInfo->enabledExtensionCount; i < n; ++i) { - extensions.push_back(pCreateInfo->pCreateInfo->ppEnabledExtensionNames[i]); + for (std::uint32_t ext_index = 0, ext_count = pCreateInfo->pCreateInfo->enabledExtensionCount; ext_index < ext_count; ++ext_index) { + extensions.push_back(pCreateInfo->pCreateInfo->ppEnabledExtensionNames[ext_index]); } - for (std::size_t i = 0, n = blocks.size(); i < n; ++i) { - const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(blocks[i].profiles.profileName); + for (std::size_t block_index = 0, block_count = blocks.size(); block_index < block_count; ++block_index) { + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(blocks[block_index].profiles.profileName); if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; - for (std::size_t j = 0, p = pProfileDesc->requiredCapabilityCount; j < p; ++j) { - const detail::VpCapabilitiesDesc* pCapsDesc = &pProfileDesc->pRequiredCapabilities[j]; + for (std::size_t caps_index = 0, caps_count = pProfileDesc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + const detail::VpCapabilitiesDesc* pCapsDesc = &pProfileDesc->pRequiredCapabilities[caps_index]; - for (std::size_t v = 0, q = pCapsDesc->variantCount; v < q; ++v) { - const detail::VpVariantDesc* variant = &pCapsDesc->pVariants[v]; + for (std::size_t variant_index = 0, variant_count = pCapsDesc->variantCount; variant_index < variant_count; ++variant_index) { + const detail::VpVariantDesc* variant = &pCapsDesc->pVariants[variant_index]; - if (strcmp(blocks[i].blockName, "") != 0) { - if (strcmp(variant->blockName, blocks[i].blockName) != 0) { + if (strcmp(blocks[block_index].blockName, "") != 0) { + if (strcmp(variant->blockName, blocks[block_index].blockName) != 0) { continue; } } - for (uint32_t t = 0; t < variant->featureStructTypeCount; ++t) { - const VkStructureType type = variant->pFeatureStructTypes[t]; + for (uint32_t type_index = 0; type_index < variant->featureStructTypeCount; ++type_index) { + const VkStructureType type = variant->pFeatureStructTypes[type_index]; if (std::find(structureTypes.begin(), structureTypes.end(), type) == std::end(structureTypes)) { structureTypes.push_back(type); } @@ -11007,21 +12287,23 @@ VPAPI_ATTR VkResult vpCreateDevice(VkPhysicalDevice physicalDevice, const VpDevi pFeatures->features = *pCreateInfo->pCreateInfo->pEnabledFeatures; } - for (std::size_t i = 0, n = blocks.size(); i < n; ++i) { - const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(blocks[i].profiles.profileName); - if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + for (std::size_t block_index = 0, block_count = blocks.size(); block_index < block_count; ++block_index) { + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(blocks[block_index].profiles.profileName); + if (pProfileDesc == nullptr) { + return VK_ERROR_UNKNOWN; + } - for (std::size_t j = 0, p = pProfileDesc->requiredCapabilityCount; j < p; ++j) { - const detail::VpCapabilitiesDesc* pCapsDesc = &pProfileDesc->pRequiredCapabilities[j]; + for (std::size_t caps_index = 0, caps_count = pProfileDesc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + const detail::VpCapabilitiesDesc* pCapsDesc = &pProfileDesc->pRequiredCapabilities[caps_index]; - for (std::size_t v = 0, q = pCapsDesc->variantCount; v < q; ++v) { - const detail::VpVariantDesc* variant = &pCapsDesc->pVariants[v]; + for (std::size_t variant_index = 0, variant_count = pCapsDesc->variantCount; variant_index < variant_count; ++variant_index) { + const detail::VpVariantDesc* variant = &pCapsDesc->pVariants[variant_index]; - VkBaseOutStructure* p = reinterpret_cast<VkBaseOutStructure*>(pFeatures); + VkBaseOutStructure* base_ptr = reinterpret_cast<VkBaseOutStructure*>(pFeatures); if (variant->feature.pfnFiller != nullptr) { - while (p != nullptr) { - variant->feature.pfnFiller(p); - p = p->pNext; + while (base_ptr != nullptr) { + variant->feature.pfnFiller(base_ptr); + base_ptr = base_ptr->pNext; } } } @@ -11041,31 +12323,63 @@ VPAPI_ATTR VkResult vpCreateDevice(VkPhysicalDevice physicalDevice, const VpDevi createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size()); createInfo.ppEnabledExtensionNames = extensions.data(); - return vkCreateDevice(physicalDevice, &createInfo, pAllocator, pDevice); + return vp.CreateDevice(physicalDevice, &createInfo, pAllocator, pDevice); } -VPAPI_ATTR VkResult vpGetProfileInstanceExtensionProperties(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) { - return detail::vpGetProfileExtensionProperties(pProfile, pBlockName, detail::EXTENSION_INSTANCE, pPropertyCount, pProperties); +VPAPI_ATTR VkResult vpGetProfileInstanceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { + return detail::vpGetProfileExtensionProperties( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::EXTENSION_INSTANCE, pPropertyCount, pProperties); } -VPAPI_ATTR VkResult vpGetProfileDeviceExtensionProperties(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) { - return detail::vpGetProfileExtensionProperties(pProfile, pBlockName, detail::EXTENSION_DEVICE, pPropertyCount, pProperties); +VPAPI_ATTR VkResult vpGetProfileDeviceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { + return detail::vpGetProfileExtensionProperties( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::EXTENSION_DEVICE, pPropertyCount, pProperties); } -VPAPI_ATTR VkResult vpGetProfileFeatures(const VpProfileProperties *pProfile, const char* pBlockName, void *pNext) { +VPAPI_ATTR VkResult vpGetProfileFeatures( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; - const std::vector<VpProfileProperties>& profiles = detail::GatherProfiles(*pProfile); + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile); - for (std::size_t profile_index = 0, profile_count = profiles.size(); profile_index < profile_count; ++profile_index) { - const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(profiles[profile_index].profileName); + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { - const detail::VpCapabilitiesDesc& capabilities = profile_desc->pRequiredCapabilities[capability_index]; + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; - for (uint32_t variant_index = 0; variant_index < capabilities.variantCount; ++variant_index) { - const detail::VpVariantDesc& variant = capabilities.pVariants[variant_index]; + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; if (pBlockName != nullptr) { if (strcmp(variant.blockName, pBlockName) != 0) { continue; @@ -11087,28 +12401,39 @@ VPAPI_ATTR VkResult vpGetProfileFeatures(const VpProfileProperties *pProfile, co return result; } -VPAPI_ATTR VkResult vpGetProfileProperties(const VpProfileProperties *pProfile, const char* pBlockName, void *pNext) { +VPAPI_ATTR VkResult vpGetProfileProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext) { VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; VkBool32 multiple_variants = VK_FALSE; - if (vpHasMultipleVariantsProfile(pProfile, &multiple_variants) == VK_ERROR_UNKNOWN) { + if (vpHasMultipleVariantsProfile( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, + &multiple_variants) == VK_ERROR_UNKNOWN) { return VK_ERROR_UNKNOWN; } if (multiple_variants == VK_TRUE && pBlockName == nullptr) { return VK_ERROR_UNKNOWN; } - const std::vector<VpProfileProperties>& profiles = detail::GatherProfiles(*pProfile); + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile); - for (std::size_t profile_index = 0, profile_count = profiles.size(); profile_index < profile_count; ++profile_index) { - const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(profiles[profile_index].profileName); + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { - const detail::VpCapabilitiesDesc& capabilities = profile_desc->pRequiredCapabilities[capability_index]; + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; - for (uint32_t variant_index = 0; variant_index < capabilities.variantCount; ++variant_index) { - const detail::VpVariantDesc& variant = capabilities.pVariants[variant_index]; + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; if (pBlockName != nullptr) { if (strcmp(variant.blockName, pBlockName) != 0) { continue; @@ -11117,7 +12442,7 @@ VPAPI_ATTR VkResult vpGetProfileProperties(const VpProfileProperties *pProfile, } if (variant.property.pfnFiller == nullptr) continue; - + VkBaseOutStructure* p = static_cast<VkBaseOutStructure*>(pNext); while (p != nullptr) { variant.property.pfnFiller(p); @@ -11130,22 +12455,98 @@ VPAPI_ATTR VkResult vpGetProfileProperties(const VpProfileProperties *pProfile, return result; } -VPAPI_ATTR VkResult vpGetProfileFormats(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pFormatCount, VkFormat *pFormats) { +VPAPI_ATTR VkResult vpGetProfileQueueFamilyProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkQueueFamilyProperties2KHR* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + if (pPropertyCount == nullptr) return VK_ERROR_UNKNOWN; + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile); + + uint32_t total_queue_family_count = 0; + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (pProperties != nullptr) { + for (uint32_t i = 0; i < variant.queueFamilyCount; ++i) { + if (total_queue_family_count < *pPropertyCount) { + if (variant.pQueueFamilies[i].pfnFiller == nullptr) continue; + + VkBaseOutStructure* p = reinterpret_cast<VkBaseOutStructure*>(pProperties); + while (p != nullptr) { + variant.pQueueFamilies[i].pfnFiller(p); + p = p->pNext; + } + + total_queue_family_count++; + pProperties++; + } else { + result = VK_INCOMPLETE; + break; + } + } + } else { + total_queue_family_count += variant.queueFamilyCount; + } + } + } + } + + *pPropertyCount = total_queue_family_count; + return result; +} + +VPAPI_ATTR VkResult vpGetProfileFormats( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pFormatCount, + VkFormat* pFormats) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; std::vector<VkFormat> results; - const std::vector<VpProfileProperties>& profiles = detail::GatherProfiles(*pProfile); + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile); - for (std::size_t profile_index = 0, profile_count = profiles.size(); profile_index < profile_count; ++profile_index) { - const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(profiles[profile_index].profileName); + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { - const detail::VpCapabilitiesDesc& capabilities = profile_desc->pRequiredCapabilities[capability_index]; + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; - for (uint32_t variant_index = 0; variant_index < capabilities.variantCount; ++variant_index) { - const detail::VpVariantDesc& variant = capabilities.pVariants[variant_index]; + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; if (pBlockName != nullptr) { if (strcmp(variant.blockName, pBlockName) != 0) { continue; @@ -11153,9 +12554,9 @@ VPAPI_ATTR VkResult vpGetProfileFormats(const VpProfileProperties *pProfile, con result = VK_SUCCESS; } - for (uint32_t i = 0; i < variant.formatCount; ++i) { - if (std::find(results.begin(), results.end(), variant.pFormats[i].format) == std::end(results)) { - results.push_back(variant.pFormats[i].format); + for (uint32_t format_index = 0; format_index < variant.formatCount; ++format_index) { + if (std::find(results.begin(), results.end(), variant.pFormats[format_index].format) == std::end(results)) { + results.push_back(variant.pFormats[format_index].format); } } } @@ -11180,13 +12581,24 @@ VPAPI_ATTR VkResult vpGetProfileFormats(const VpProfileProperties *pProfile, con return result; } -VPAPI_ATTR VkResult vpGetProfileFormatProperties(const VpProfileProperties *pProfile, const char* pBlockName, VkFormat format, void *pNext) { +VPAPI_ATTR VkResult vpGetProfileFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + VkFormat format, + void* pNext) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; - const std::vector<VpProfileProperties>& profiles = detail::GatherProfiles(*pProfile); + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile); - for (std::size_t i = 0, n = profiles.size(); i < n; ++i) { - const char* profile_name = profiles[i].profileName; + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const char* profile_name = gathered_profiles[profile_index].profileName; const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(profile_name); if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; @@ -11204,15 +12616,15 @@ VPAPI_ATTR VkResult vpGetProfileFormatProperties(const VpProfileProperties *pPro result = VK_SUCCESS; } - for (uint32_t i = 0; i < variant.formatCount; ++i) { - if (variant.pFormats[i].format != format) { + for (uint32_t format_index = 0; format_index < variant.formatCount; ++format_index) { + if (variant.pFormats[format_index].format != format) { continue; } - VkBaseOutStructure* p = static_cast<VkBaseOutStructure*>(static_cast<void*>(pNext)); - while (p != nullptr) { - variant.pFormats[i].pfnFiller(p); - p = p->pNext; + VkBaseOutStructure* base_ptr = static_cast<VkBaseOutStructure*>(static_cast<void*>(pNext)); + while (base_ptr != nullptr) { + variant.pFormats[format_index].pfnFiller(base_ptr); + base_ptr = base_ptr->pNext; } #if defined(VK_VERSION_1_3) || defined(VK_KHR_format_feature_flags2) VkFormatProperties2KHR* fp2 = static_cast<VkFormatProperties2KHR*>( @@ -11221,14 +12633,14 @@ VPAPI_ATTR VkResult vpGetProfileFormatProperties(const VpProfileProperties *pPro detail::vpGetStructure(pNext, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR)); if (fp3 != nullptr) { VkFormatProperties2KHR fp{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR }; - variant.pFormats[i].pfnFiller(static_cast<VkBaseOutStructure*>(static_cast<void*>(&fp))); + variant.pFormats[format_index].pfnFiller(static_cast<VkBaseOutStructure*>(static_cast<void*>(&fp))); fp3->linearTilingFeatures |= static_cast<VkFormatFeatureFlags2KHR>(fp3->linearTilingFeatures | fp.formatProperties.linearTilingFeatures); fp3->optimalTilingFeatures |= static_cast<VkFormatFeatureFlags2KHR>(fp3->optimalTilingFeatures | fp.formatProperties.optimalTilingFeatures); fp3->bufferFeatures |= static_cast<VkFormatFeatureFlags2KHR>(fp3->bufferFeatures | fp.formatProperties.bufferFeatures); } if (fp2 != nullptr) { VkFormatProperties3KHR fp{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR }; - variant.pFormats[i].pfnFiller(static_cast<VkBaseOutStructure*>(static_cast<void*>(&fp))); + variant.pFormats[format_index].pfnFiller(static_cast<VkBaseOutStructure*>(static_cast<void*>(&fp))); fp2->formatProperties.linearTilingFeatures |= static_cast<VkFormatFeatureFlags>(fp2->formatProperties.linearTilingFeatures | fp.linearTilingFeatures); fp2->formatProperties.optimalTilingFeatures |= static_cast<VkFormatFeatureFlags>(fp2->formatProperties.optimalTilingFeatures | fp.optimalTilingFeatures); fp2->formatProperties.bufferFeatures |= static_cast<VkFormatFeatureFlags>(fp2->formatProperties.bufferFeatures | fp.bufferFeatures); @@ -11242,16 +12654,316 @@ VPAPI_ATTR VkResult vpGetProfileFormatProperties(const VpProfileProperties *pPro return result; } -VPAPI_ATTR VkResult vpGetProfileFeatureStructureTypes(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pStructureTypeCount, VkStructureType *pStructureTypes) { - return detail::vpGetProfileStructureTypes(pProfile, pBlockName, detail::STRUCTURE_FEATURE, pStructureTypeCount, pStructureTypes); +VPAPI_ATTR VkResult vpGetProfileFeatureStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_FEATURE, pStructureTypeCount, pStructureTypes); } -VPAPI_ATTR VkResult vpGetProfilePropertyStructureTypes(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pStructureTypeCount, VkStructureType *pStructureTypes) { - return detail::vpGetProfileStructureTypes(pProfile, pBlockName, detail::STRUCTURE_PROPERTY, pStructureTypeCount, pStructureTypes); +VPAPI_ATTR VkResult vpGetProfilePropertyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_PROPERTY, pStructureTypeCount, pStructureTypes); } -VPAPI_ATTR VkResult vpGetProfileFormatStructureTypes(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pStructureTypeCount, VkStructureType *pStructureTypes) { - return detail::vpGetProfileStructureTypes(pProfile, pBlockName, detail::STRUCTURE_FORMAT, pStructureTypeCount, pStructureTypes); +VPAPI_ATTR VkResult vpGetProfileQueueFamilyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_QUEUE_FAMILY, pStructureTypeCount, pStructureTypes); } -// clang-format on +VPAPI_ATTR VkResult vpGetProfileFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_FORMAT, pStructureTypeCount, pStructureTypes); +} + +#ifdef VK_KHR_video_queue +// Query the list of video profiles specified by the profile +VPAPI_ATTR VkResult vpGetProfileVideoProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pVideoProfileCount, + VpVideoProfileProperties* pVideoProfiles) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + if (pVideoProfileCount == nullptr) return VK_ERROR_UNKNOWN; + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + uint32_t total_video_profile_count = 0; + + const std::vector<VpProfileProperties>& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (pVideoProfiles != nullptr) { + for (uint32_t i = 0; i < variant.videoProfileCount; ++i) { + if (total_video_profile_count < *pVideoProfileCount) { + *pVideoProfiles = variant.pVideoProfiles[i].properties; + total_video_profile_count++; + pVideoProfiles++; + } else { + result = VK_INCOMPLETE; + break; + } + } + } else { + total_video_profile_count += variant.videoProfileCount; + } + } + } + } + + *pVideoProfileCount = total_video_profile_count; + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfo( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + VkVideoProfileInfoKHR* pVideoProfileInfo) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + VkBaseOutStructure* p = reinterpret_cast<VkBaseOutStructure*>(pVideoProfileInfo); + while (p != nullptr) { + pVideoProfileDesc->info.pfnFiller(p); + p = p->pNext; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoCapabilities( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + void* pNext) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + VkBaseOutStructure* p = reinterpret_cast<VkBaseOutStructure*>(pNext); + while (p != nullptr) { + pVideoProfileDesc->capability.pfnFiller(p); + p = p->pNext; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pPropertyCount, + VkVideoFormatPropertiesKHR* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + uint32_t property_count = 0; + if (pVideoProfileDesc != nullptr) { + if (pProperties != nullptr) { + for (; property_count < pVideoProfileDesc->formatCount; ++property_count) { + if (property_count < *pPropertyCount) { + VkBaseOutStructure* p = reinterpret_cast<VkBaseOutStructure*>(&pProperties[property_count]); + while (p != nullptr) { + pVideoProfileDesc->pFormats[property_count].pfnFiller(p); + p = p->pNext; + } + } else { + result = VK_INCOMPLETE; + break; + } + } + } else { + property_count = pVideoProfileDesc->formatCount; + } + } + + *pPropertyCount = property_count; + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfoStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + if (pStructureTypes != nullptr) { + if (*pStructureTypeCount < pVideoProfileDesc->infoStructTypeCount) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = pVideoProfileDesc->infoStructTypeCount; + } + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, pVideoProfileDesc->pInfoStructTypes, *pStructureTypeCount * sizeof(VkStructureType)); + } + } else { + *pStructureTypeCount = pVideoProfileDesc->infoStructTypeCount; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoCapabilityStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + if (pStructureTypes != nullptr) { + if (*pStructureTypeCount < pVideoProfileDesc->capabilityStructTypeCount) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = pVideoProfileDesc->capabilityStructTypeCount; + } + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, pVideoProfileDesc->pCapabilityStructTypes, *pStructureTypeCount * sizeof(VkStructureType)); + } + } else { + *pStructureTypeCount = pVideoProfileDesc->capabilityStructTypeCount; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + if (pStructureTypes != nullptr) { + if (*pStructureTypeCount < pVideoProfileDesc->formatStructTypeCount) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = pVideoProfileDesc->formatStructTypeCount; + } + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, pVideoProfileDesc->pFormatStructTypes, *pStructureTypeCount * sizeof(VkStructureType)); + } + } else { + *pStructureTypeCount = pVideoProfileDesc->formatStructTypeCount; + } + } + + return result; +} +#endif // VK_KHR_video_queue diff --git a/vulkan/vkprofiles/generated/vulkan_profiles.h b/vulkan/vkprofiles/generated/vulkan_profiles.h index 4bfb6f6945..c29e340716 100644 --- a/vulkan/vkprofiles/generated/vulkan_profiles.h +++ b/vulkan/vkprofiles/generated/vulkan_profiles.h @@ -91,6 +91,32 @@ #define VP_ANDROID_15_MINIMUMS_MIN_API_VERSION VK_MAKE_VERSION(1, 3, 273) #endif +#if defined(VK_VERSION_1_3) && \ + defined(VP_ANDROID_15_minimums) && \ + defined(VP_ANDROID_baseline_2022) && \ + defined(VK_EXT_host_image_copy) && \ + defined(VK_EXT_image_2d_view_of_3d) && \ + defined(VK_EXT_multisampled_render_to_single_sampled) && \ + defined(VK_EXT_pipeline_protected_access) && \ + defined(VK_EXT_pipeline_robustness) && \ + defined(VK_EXT_shader_stencil_export) && \ + defined(VK_EXT_transform_feedback) && \ + defined(VK_KHR_8bit_storage) && \ + defined(VK_KHR_load_store_op_none) && \ + defined(VK_KHR_maintenance6) && \ + defined(VK_KHR_map_memory2) && \ + defined(VK_KHR_shader_expect_assume) && \ + defined(VK_KHR_shader_float_controls2) && \ + defined(VK_KHR_shader_maximal_reconvergence) && \ + defined(VK_KHR_shader_subgroup_rotate) && \ + defined(VK_KHR_shader_subgroup_uniform_control_flow) && \ + defined(VK_KHR_swapchain_mutable_format) +#define VP_ANDROID_16_minimums 1 +#define VP_ANDROID_16_MINIMUMS_NAME "VP_ANDROID_16_minimums" +#define VP_ANDROID_16_MINIMUMS_SPEC_VERSION 1 +#define VP_ANDROID_16_MINIMUMS_MIN_API_VERSION VK_MAKE_VERSION(1, 3, 276) +#endif + #if defined(VK_VERSION_1_0) && \ defined(VK_EXT_swapchain_colorspace) && \ defined(VK_GOOGLE_display_timing) && \ @@ -161,6 +187,10 @@ typedef struct VpBlockProperties { char blockName[VP_MAX_PROFILE_NAME_SIZE]; } VpBlockProperties; +typedef struct VpVideoProfileProperties { + char name[VP_MAX_PROFILE_NAME_SIZE]; +} VpVideoProfileProperties; + typedef enum VpInstanceCreateFlagBits { VP_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VpInstanceCreateFlagBits; @@ -194,70 +224,342 @@ typedef struct VpDeviceCreateInfo { const VpBlockProperties* pEnabledProfileBlocks; } VpDeviceCreateInfo; +VK_DEFINE_HANDLE(VpCapabilities) + +typedef enum VpCapabilitiesCreateFlagBits { + VP_PROFILE_CREATE_STATIC_BIT = (1 << 0), + //VP_PROFILE_CREATE_DYNAMIC_BIT = (1 << 1), + VP_PROFILE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VpCapabilitiesCreateFlagBits; + +typedef VkFlags VpCapabilitiesCreateFlags; + +// Pointers to some Vulkan functions - a subset used by the library. +// Used in VpCapabilitiesCreateInfo::pVulkanFunctions. + +typedef struct VpVulkanFunctions { + /// Required when using VP_DYNAMIC_VULKAN_FUNCTIONS. + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; + /// Required when using VP_DYNAMIC_VULKAN_FUNCTIONS. + PFN_vkGetDeviceProcAddr GetDeviceProcAddr; + PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion; + PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; + PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; + PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2; + PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2; + PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2; + PFN_vkCreateInstance CreateInstance; + PFN_vkCreateDevice CreateDevice; +} VpVulkanFunctions; + +/// Description of a Allocator to be created. +typedef struct VpCapabilitiesCreateInfo +{ + /// Flags for created allocator. Use #VpInstanceCreateFlagBits enum. + VpCapabilitiesCreateFlags flags; + uint32_t apiVersion; + const VpVulkanFunctions* pVulkanFunctions; +} VpCapabilitiesCreateInfo; + +VPAPI_ATTR VkResult vpCreateCapabilities( + const VpCapabilitiesCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VpCapabilities* pCapabilities); + +/// Destroys allocator object. +VPAPI_ATTR void vpDestroyCapabilities( + VpCapabilities capabilities, + const VkAllocationCallbacks* pAllocator); + // Query the list of available profiles in the library -VPAPI_ATTR VkResult vpGetProfiles(uint32_t *pPropertyCount, VpProfileProperties *pProperties); +VPAPI_ATTR VkResult vpGetProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + uint32_t* pPropertyCount, + VpProfileProperties* pProperties); // List the required profiles of a profile -VPAPI_ATTR VkResult vpGetProfileRequiredProfiles(const VpProfileProperties* pProfile, uint32_t* pPropertyCount, VpProfileProperties* pProperties); +VPAPI_ATTR VkResult vpGetProfileRequiredProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties); // Query the profile required Vulkan API version -VPAPI_ATTR uint32_t vpGetProfileAPIVersion(const VpProfileProperties* pProfile); +VPAPI_ATTR uint32_t vpGetProfileAPIVersion( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile); // List the recommended fallback profiles of a profile -VPAPI_ATTR VkResult vpGetProfileFallbacks(const VpProfileProperties *pProfile, uint32_t *pPropertyCount, VpProfileProperties *pProperties); +VPAPI_ATTR VkResult vpGetProfileFallbacks( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties); // Query whether the profile has multiple variants. Profiles with multiple variants can only use vpGetInstanceProfileSupport and vpGetPhysicalDeviceProfileSupport capabilities of the library. Other function will return a VK_ERROR_UNKNOWN error -VPAPI_ATTR VkResult vpHasMultipleVariantsProfile(const VpProfileProperties *pProfile, VkBool32 *pHasMultipleVariants); +VPAPI_ATTR VkResult vpHasMultipleVariantsProfile( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + VkBool32* pHasMultipleVariants); // Check whether a profile is supported at the instance level -VPAPI_ATTR VkResult vpGetInstanceProfileSupport(const char *pLayerName, const VpProfileProperties *pProfile, VkBool32 *pSupported); +VPAPI_ATTR VkResult vpGetInstanceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported); // Check whether a variant of a profile is supported at the instance level and report this list of blocks used to validate the profiles -VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport(const char *pLayerName, const VpProfileProperties *pProfile, VkBool32 *pSupported, uint32_t *pPropertyCount, VpBlockProperties* pProperties); +VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + uint32_t* pPropertyCount, + VpBlockProperties* pProperties); // Create a VkInstance with the profile instance extensions enabled -VPAPI_ATTR VkResult vpCreateInstance(const VpInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance); +VPAPI_ATTR VkResult vpCreateInstance( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance); // Check whether a profile is supported by the physical device -VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileSupport(VkInstance instance, VkPhysicalDevice physicalDevice, const VpProfileProperties *pProfile, VkBool32 *pSupported); +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties* pProfile, + VkBool32* pSupported); // Check whether a variant of a profile is supported by the physical device and report this list of blocks used to validate the profiles -VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport(VkInstance instance, VkPhysicalDevice physicalDevice, const VpProfileProperties *pProfile, VkBool32 *pSupported, uint32_t *pPropertyCount, VpBlockProperties* pProperties); +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + uint32_t* pPropertyCount, + VpBlockProperties* pProperties); // Create a VkDevice with the profile features and device extensions enabled -VPAPI_ATTR VkResult vpCreateDevice(VkPhysicalDevice physicalDevice, const VpDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice); +VPAPI_ATTR VkResult vpCreateDevice( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkPhysicalDevice physicalDevice, + const VpDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice); // Query the list of instance extensions of a profile -VPAPI_ATTR VkResult vpGetProfileInstanceExtensionProperties(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); +VPAPI_ATTR VkResult vpGetProfileInstanceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); // Query the list of device extensions of a profile -VPAPI_ATTR VkResult vpGetProfileDeviceExtensionProperties(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); +VPAPI_ATTR VkResult vpGetProfileDeviceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); // Fill the feature structures with the requirements of a profile -VPAPI_ATTR VkResult vpGetProfileFeatures(const VpProfileProperties *pProfile, const char* pBlockName, void *pNext); +VPAPI_ATTR VkResult vpGetProfileFeatures( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext); // Query the list of feature structure types specified by the profile -VPAPI_ATTR VkResult vpGetProfileFeatureStructureTypes(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pStructureTypeCount, VkStructureType *pStructureTypes); +VPAPI_ATTR VkResult vpGetProfileFeatureStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); // Fill the property structures with the requirements of a profile -VPAPI_ATTR VkResult vpGetProfileProperties(const VpProfileProperties *pProfile, const char* pBlockName, void *pNext); +VPAPI_ATTR VkResult vpGetProfileProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext); // Query the list of property structure types specified by the profile -VPAPI_ATTR VkResult vpGetProfilePropertyStructureTypes(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pStructureTypeCount, VkStructureType *pStructureTypes); +VPAPI_ATTR VkResult vpGetProfilePropertyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Fill the queue family property structures with the requirements of a profile +VPAPI_ATTR VkResult vpGetProfileQueueFamilyProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkQueueFamilyProperties2KHR* pProperties); + +// Query the list of queue family property structure types specified by the profile +VPAPI_ATTR VkResult vpGetProfileQueueFamilyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); // Query the list of formats with specified requirements by a profile -VPAPI_ATTR VkResult vpGetProfileFormats(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pFormatCount, VkFormat *pFormats); +VPAPI_ATTR VkResult vpGetProfileFormats( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pFormatCount, + VkFormat* pFormats); // Query the requirements of a format for a profile -VPAPI_ATTR VkResult vpGetProfileFormatProperties(const VpProfileProperties *pProfile, const char* pBlockName, VkFormat format, void *pNext); +VPAPI_ATTR VkResult vpGetProfileFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + VkFormat format, + void* pNext); // Query the list of format structure types specified by the profile -VPAPI_ATTR VkResult vpGetProfileFormatStructureTypes(const VpProfileProperties *pProfile, const char* pBlockName, uint32_t *pStructureTypeCount, VkStructureType *pStructureTypes); +VPAPI_ATTR VkResult vpGetProfileFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +#ifdef VK_KHR_video_queue +// Query the list of video profiles specified by the profile +VPAPI_ATTR VkResult vpGetProfileVideoProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pVideoProfileCount, + VpVideoProfileProperties* pVideoProfiles); + +// Query the video profile info structures for a video profile defined by a profile +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfo( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + VkVideoProfileInfoKHR* pVideoProfileInfo); + +// Query the list of video profile info structure types specified by the profile for a video profile +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfoStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Query the video capabilities requirements for a video profile defined by a profile +VPAPI_ATTR VkResult vpGetProfileVideoCapabilities( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + void* pNext); + +// Query the list of video capability structure types specified by the profile for a video profile +VPAPI_ATTR VkResult vpGetProfileVideoCapabilityStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Query the video format property requirements for a video profile defined by a profile +VPAPI_ATTR VkResult vpGetProfileVideoFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pPropertyCount, + VkVideoFormatPropertiesKHR* pProperties); + +// Query the list of video format property structure types specified by the profile for a video profile +VPAPI_ATTR VkResult vpGetProfileVideoFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); +#endif // VK_KHR_video_queue #ifdef __cplusplus } #endif #endif // VULKAN_PROFILES_H_ - -// clang-format on diff --git a/vulkan/vkprofiles/profiles/VP_ANDROID_16_minimums.json b/vulkan/vkprofiles/profiles/VP_ANDROID_16_minimums.json new file mode 100644 index 0000000000..c49e68ad43 --- /dev/null +++ b/vulkan/vkprofiles/profiles/VP_ANDROID_16_minimums.json @@ -0,0 +1,154 @@ +{ + "$schema": "https://schema.khronos.org/vulkan/profiles-0.8.2-301.json#", + "capabilities": { + "MUST": { + "extensions": { + "VK_KHR_8bit_storage": 1, + "VK_KHR_load_store_op_none": 1, + "VK_KHR_maintenance6": 1, + "VK_KHR_map_memory2": 1, + "VK_KHR_shader_expect_assume": 1, + "VK_KHR_shader_float_controls2": 1, + "VK_KHR_shader_maximal_reconvergence": 1, + "VK_KHR_shader_subgroup_rotate": 1, + "VK_KHR_shader_subgroup_uniform_control_flow": 1, + "VK_KHR_swapchain_mutable_format": 1, + "VK_EXT_host_image_copy": 1, + "VK_EXT_image_2d_view_of_3d": 1, + "VK_EXT_pipeline_protected_access": 1, + "VK_EXT_pipeline_robustness": 1, + "VK_EXT_transform_feedback": 1 + }, + "features": { + "VkPhysicalDeviceFeatures": { + "fullDrawIndexUint32": true, + "shaderInt16": true + }, + "VkPhysicalDeviceVulkan12Features": { + "samplerMirrorClampToEdge": true, + "scalarBlockLayout": true + }, + "VkPhysicalDeviceProtectedMemoryFeatures": { + "protectedMemory": true + }, + "VkPhysicalDeviceShaderIntegerDotProductFeatures": { + "shaderIntegerDotProduct": true + }, + "VkPhysicalDeviceTransformFeedbackFeaturesEXT": { + "transformFeedback": true + }, + "VkPhysicalDeviceImage2DViewOf3DFeaturesEXT": { + "image2DViewOf3D": true + }, + "VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR": { + "shaderSubgroupUniformControlFlow": true + } + }, + "properties": { + "VkPhysicalDeviceProperties": { + "limits": { + "bufferImageGranularity": 4096, + "lineWidthGranularity": 0.5, + "maxColorAttachments": 8, + "maxComputeWorkGroupInvocations": 256, + "maxComputeWorkGroupSize": [ 256, 256, 64 ], + "maxImageArrayLayers": 2048, + "maxImageDimension1D": 8192, + "maxImageDimension2D": 8192, + "maxImageDimensionCube": 8192, + "maxDescriptorSetStorageBuffers": 96, + "maxDescriptorSetUniformBuffers": 90, + "maxFragmentCombinedOutputResources": 16, + "maxPerStageDescriptorUniformBuffers": 15, + "maxPerStageResources": 200, + "maxSamplerLodBias": 14, + "maxUniformBufferRange": 65536, + "maxVertexOutputComponents": 72, + "mipmapPrecisionBits": 6, + "pointSizeGranularity": 0.125, + "standardSampleLocations": true, + "subTexelPrecisionBits": 8, + "timestampComputeAndGraphics": true + } + }, + "VkPhysicalDeviceFloatControlsProperties": { + "shaderSignedZeroInfNanPreserveFloat16": true, + "shaderSignedZeroInfNanPreserveFloat32": true + }, + "VkPhysicalDeviceVulkan11Properties": { + "subgroupSupportedStages": ["VK_SHADER_STAGE_COMPUTE_BIT"] + } + } + }, + "multisampledToSingleSampled": { + "extensions": { + "VK_EXT_multisampled_render_to_single_sampled": 1 + } + }, + "shaderStencilExport": { + "extensions": { + "VK_EXT_shader_stencil_export": 1 + } + } + }, + "profiles": { + "VP_ANDROID_16_minimums": { + "version": 1, + "api-version": "1.3.276", + "label": "Vulkan Minimum Requirements for Android 16", + "description": "Collection of functionality that is mandated on Android 16", + "contributors": { + "Ian Elliott": { + "company": "Google", + "email": "ianelliott@google.com", + "contact": true + } + }, + "history": [ + { + "revision": 1, + "date": "2024-02-20", + "author": "Ian Elliott", + "comment": "First draft" + }, + { + "revision": 2, + "date": "2024-07-22", + "author": "Ian Elliott", + "comment": "Added proposed Vulkan 1.4 scope" + }, + { + "revision": 3, + "date": "2024-11-15", + "author": "Ian Elliott", + "comment": "Delay some requirements that Mali Bifrost chipsets cannot do" + }, + { + "revision": 4, + "date": "2024-12-10", + "author": "Ian Elliott", + "comment": "Delay some requirements that Adreno A6xx chipsets cannot do" + }, + { + "revision": 5, + "date": "2024-12-11", + "author": "Ian Elliott", + "comment": "Delay VK_EXT_device_fault" + }, + { + "revision": 6, + "date": "2024-12-11", + "author": "Ian Elliott", + "comment": "Delay a requirement that IMG BXM-8-256 chipsets cannot do" + } + ], + "profiles": [ + "VP_ANDROID_15_minimums" + ], + "capabilities": [ + "MUST", + ["multisampledToSingleSampled", "shaderStencilExport"] + ] + } + } +} diff --git a/vulkan/vkprofiles/vkprofiles.cpp b/vulkan/vkprofiles/vkprofiles.cpp index 465dc254fd..e5ad9022bb 100644 --- a/vulkan/vkprofiles/vkprofiles.cpp +++ b/vulkan/vkprofiles/vkprofiles.cpp @@ -182,6 +182,13 @@ std::string vkVpa15GetSupport() { VP_ANDROID_15_MINIMUMS_MIN_API_VERSION); } +std::string vkVpa16GetSupport() { + VpProfileProperties profile{VP_ANDROID_16_MINIMUMS_NAME, + VP_ANDROID_16_MINIMUMS_SPEC_VERSION}; + return vkProfileGetSupport(&profile, + VP_ANDROID_16_MINIMUMS_MIN_API_VERSION); +} + std::string vkProfiles() { return "{" "\"" + std::string(VP_ANDROID_BASELINE_2021_NAME) + "\": " @@ -191,7 +198,9 @@ std::string vkProfiles() { "\"" + std::string(VP_ANDROID_BASELINE_2022_NAME) + "\": " "\"" + vkAbp2022GetSupport() + "\"," "\"" + std::string(VP_ANDROID_15_MINIMUMS_NAME) + "\": " - "\"" + vkVpa15GetSupport() + "\"" + "\"" + vkVpa15GetSupport() + "\"," + "\"" + std::string(VP_ANDROID_16_MINIMUMS_NAME) + "\": " + "\"" + vkVpa16GetSupport() + "\"" "}"; } diff --git a/vulkan/vkprofiles/vkprofiles.h b/vulkan/vkprofiles/vkprofiles.h index 8f42e9bc30..a4116086bd 100644 --- a/vulkan/vkprofiles/vkprofiles.h +++ b/vulkan/vkprofiles/vkprofiles.h @@ -32,6 +32,7 @@ std::string vkAbp2021GetSupport(); std::string vkAbp2021GetSupportCpuOnly(); std::string vkAbp2022GetSupport(); std::string vkVpa15GetSupport(); +std::string vkVpa16GetSupport(); // Returns a json string that enumerates support for any of the Vulkan profiles // specified in the above functions |