diff options
475 files changed, 22642 insertions, 9922 deletions
@@ -1,3 +1,3 @@ -third_party { + third_party { license_type: NOTICE } 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/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp index a5d176d8c4..fdb032b285 100644 --- a/cmds/dumpstate/Android.bp +++ b/cmds/dumpstate/Android.bp @@ -117,6 +117,7 @@ cc_defaults { "libdumpsys", "libserviceutils", "android.tracing.flags_c_lib", + "perfetto_flags_c_lib", ], } diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index 888fb67b31..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> @@ -190,7 +191,7 @@ 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" @@ -359,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 @@ -1101,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() { @@ -3412,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; } @@ -3560,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/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/servicemanager/Access.cpp b/cmds/servicemanager/Access.cpp index 809872417d..6e2abf65e2 100644 --- a/cmds/servicemanager/Access.cpp +++ b/cmds/servicemanager/Access.cpp @@ -34,7 +34,9 @@ constexpr bool kIsVendor = false; #ifdef __ANDROID__ static std::string getPidcon(pid_t pid) { - android_errorWriteLog(0x534e4554, "121035042"); + CHECK_EQ(nullptr, IPCThreadState::self()->getServingStackPointer()) + << "Did not get context from PID " << pid + << ". We should always get contexts from other processes."; char* lookup = nullptr; if (getpidcon(pid, &lookup) < 0) { diff --git a/data/etc/Android.bp b/data/etc/Android.bp index 64ef8278e4..0ac5266a0c 100644 --- a/data/etc/Android.bp +++ b/data/etc/Android.bp @@ -305,12 +305,24 @@ prebuilt_etc { } prebuilt_etc { + name: "android.hardware.telephony.satellite.prebuilt.xml", + src: "android.hardware.telephony.satellite.xml", + defaults: ["frameworks_native_data_etc_defaults"], +} + +prebuilt_etc { name: "android.hardware.telephony.ims.singlereg.prebuilt.xml", src: "android.hardware.telephony.ims.singlereg.xml", defaults: ["frameworks_native_data_etc_defaults"], } 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"], 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/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/performance_hint.h b/include/android/performance_hint.h index 2b4a5f5f53..52dbb61ac5 100644 --- a/include/android/performance_hint.h +++ b/include/android/performance_hint.h @@ -29,7 +29,7 @@ * workloads are taking. The framework will then compare the actual durations to the target * duration and attempt to help the client reach a steady state under the target. * - * Unlike reportActualWorkDuration, the "notify..." hints are intended to be sent in + * Unlike reportActualWorkDuration, the "notifyWorkload..." hints are intended to be sent in * advance of large changes in the workload, to prevent them from going over the target * when there is a sudden, unforseen change. Their effects are intended to last for only * one cycle, after which reportActualWorkDuration will have a chance to catch up. @@ -71,6 +71,10 @@ #include <stdint.h> #include <unistd.h> +#if !defined(__DEPRECATED_IN) +#define __DEPRECATED_IN(__api_level, ...) __attribute__((__deprecated__)) +#endif + __BEGIN_DECLS struct APerformanceHintManager; @@ -116,13 +120,13 @@ typedef struct APerformanceHintManager APerformanceHintManager; * An opaque type representing a handle to a performance hint session creation configuration. * It is consumed by {@link APerformanceHint_createSessionUsingConfig}. * - * A session creation config encapsulates the required information for a session. - * Additionally, the caller can set various settings for the session, - * to be passed during creation, streamlining the session setup process. - * - * The caller may reuse this object and modify the settings in it - * to create additional sessions. + * A session creation config encapsulates the required information for creating a session. The only + * mandatory parameter is the set of TIDs, set using {@link ASessionCreationConfig_setTids}. Only + * parameters relevant to the session need to be set, and any unspecified functionality will be + * treated as unused on the session. Configurations without a valid set of TIDs, or which try to + * enable automatic timing without the graphics pipeline mode, are considered invalid. * + * The caller may reuse this object and modify the settings in it to create additional sessions. */ typedef struct ASessionCreationConfig ASessionCreationConfig; @@ -181,27 +185,43 @@ APerformanceHintSession* _Nullable APerformanceHint_createSession( int64_t initialTargetWorkDurationNanos) __INTRODUCED_IN(__ANDROID_API_T__); /** - * Creates a session for the given set of threads that are graphics pipeline threads - * and set their initial target work duration. + * Creates a session using arguments from a corresponding {@link ASessionCreationConfig}. + * + * Note: when using graphics pipeline mode, using too many cumulative graphics pipeline threads is + * not a failure and will still create a session, but it will cause all graphics pipeline sessions + * to have undefined behavior and the method will return EBUSY. * * @param manager The performance hint manager instance. * @param config The configuration struct containing required information * to create a session. - * @return APerformanceHintSession pointer on success, nullptr on failure. + * @param sessionOut A client-provided pointer, which will be set to the new APerformanceHintSession + * on success or EBUSY, and to nullptr on failure. + * + * @return 0 on success. + * EINVAL if the creation config is in an invalid state. + * EPIPE if communication failed. + * ENOTSUP if hint sessions are not supported, or if auto timing is enabled but unsupported. + * EBUSY if too many graphics pipeline threads are passed. */ -APerformanceHintSession* _Nullable APerformanceHint_createSessionUsingConfig( +int APerformanceHint_createSessionUsingConfig( APerformanceHintManager* _Nonnull manager, - ASessionCreationConfig* _Nonnull config) - __INTRODUCED_IN(36); + ASessionCreationConfig* _Nonnull config, + APerformanceHintSession * _Nullable * _Nonnull sessionOut) __INTRODUCED_IN(36); /** * Get preferred update rate information for this device. * + * @deprecated Client side rate limiting is not necessary, rate limiting is handled in the + * framework. If you were using this to check for hint session support, please use + * {@link APerformanceHint_isFeatureSupported} instead. + * * @param manager The performance hint manager instance. * @return the preferred update rate supported by device software. */ int64_t APerformanceHint_getPreferredUpdateRateNanos( - APerformanceHintManager* _Nonnull manager) __INTRODUCED_IN(__ANDROID_API_T__); + APerformanceHintManager* _Nonnull manager) + __INTRODUCED_IN(__ANDROID_API_T__) __DEPRECATED_IN(36, "Client-side rate limiting is not" + " necessary, use APerformanceHint_isFeatureSupported for support checking."); /** * Get maximum number of graphics pipieline threads per-app for this device. @@ -216,9 +236,11 @@ int64_t APerformanceHint_getPreferredUpdateRateNanos( * Updates this session's target duration for each cycle of work. * * @param session The performance hint session instance to update. - * @param targetDurationNanos The new desired duration in nanoseconds. This must be positive. + * @param targetDurationNanos The new desired duration in nanoseconds. This must be positive for the + * session to report work durations, and may be zero to disable this functionality. + * * @return 0 on success. - * EINVAL if targetDurationNanos is not positive. + * EINVAL if targetDurationNanos is less than zero. * EPIPE if communication with the system service has failed. */ int APerformanceHint_updateTargetWorkDuration( @@ -235,7 +257,7 @@ int APerformanceHint_updateTargetWorkDuration( * @param actualDurationNanos The duration of time the thread group took to complete its last * task in nanoseconds. This must be positive. * @return 0 on success. - * EINVAL if actualDurationNanos is not positive. + * EINVAL if actualDurationNanos is not positive or the target it not positive. * EPIPE if communication with the system service has failed. */ int APerformanceHint_reportActualWorkDuration( @@ -258,15 +280,20 @@ void APerformanceHint_closeSession( * Set a list of threads to the performance hint session. This operation will replace * the current list of threads with the given list of threads. * + * Note: when using a session with the graphics pipeline mode enabled, using too many cumulative + * graphics pipeline threads is not a failure, but it will cause all graphics pipeline sessions to + * have undefined behavior and the method will return EBUSY. + * * @param session The performance hint session instance to update. * @param threadIds The list of threads to be associated with this session. They must be part of * this app's thread group. * @param size The size of the list of threadIds. * @return 0 on success. * EINVAL if the list of thread ids is empty or if any of the thread ids are not part of - the thread group. + * the thread group. * EPIPE if communication with the system service has failed. * EPERM if any thread id doesn't belong to the application. + * EBUSY if too many graphics pipeline threads were passed. */ int APerformanceHint_setThreads( APerformanceHintSession* _Nonnull session, @@ -311,89 +338,102 @@ int APerformanceHint_reportActualWorkDuration2( AWorkDuration* _Nonnull workDuration) __INTRODUCED_IN(__ANDROID_API_V__); /** - * Informs the framework of an upcoming increase in the workload of a graphics pipeline - * bound to this session. The user can specify whether the increase is expected to be - * on the CPU, GPU, or both. + * Informs the framework of an upcoming increase in the workload of this session. + * The user can specify whether the increase is expected to be on the CPU, GPU, or both. * - * Sending hints for both CPU and GPU counts as two separate hints for the purposes of the - * rate limiter. + * These hints should be sent shortly before the start of the cycle where the workload is going to + * change, or as early as possible during that cycle for maximum effect. Hints sent towards the end + * of the cycle may be interpreted as applying to the next cycle. Any unsupported hints will be + * silently dropped, to avoid the need for excessive support checking each time they are sent, and + * sending a hint for both CPU and GPU will count as two separate hints for the rate limiter. These + * hints should not be sent repeatedly for an ongoing expensive workload, as workload time reporting + * is intended to handle this. * + * @param session The {@link APerformanceHintSession} instance to send a hint for. * @param cpu Indicates if the workload increase is expected to affect the CPU. * @param gpu Indicates if the workload increase is expected to affect the GPU. - * @param debugName A required string used to identify this specific hint during - * tracing. This debug string will only be held for the duration of the - * method, and can be safely discarded after. + * @param identifier A required string used to distinguish this specific hint, using utf-8 encoding. + * This string will only be held for the duration of the method, and can be discarded after. * * @return 0 on success. - * EINVAL if no hints were requested. * EBUSY if the hint was rate limited. * EPIPE if communication with the system service has failed. - * ENOTSUP if the hint is not supported. */ int APerformanceHint_notifyWorkloadIncrease( APerformanceHintSession* _Nonnull session, - bool cpu, bool gpu, const char* _Nonnull debugName) __INTRODUCED_IN(36); + bool cpu, bool gpu, const char* _Nonnull identifier) __INTRODUCED_IN(36); /** - * Informs the framework of an upcoming reset in the workload of a graphics pipeline - * bound to this session, or the imminent start of a new workload. The user can specify - * whether the reset is expected to affect the CPU, GPU, or both. + * Informs the framework that the workload associated with this session is about to start, or that + * it is about to completely change, and that the system should discard any assumptions about its + * characteristics inferred from previous activity. The user can specify whether the reset is + * expected to affect the CPU, GPU, or both. * - * Sending hints for both CPU and GPU counts as two separate hints for the purposes of the - * this load tracking. + * These hints should be sent shortly before the start of the cycle where the workload is going to + * change, or as early as possible during that cycle for maximum effect. Hints sent towards the end + * of the cycle may be interpreted as applying to the next cycle. Any unsupported hints will be + * silently dropped, to avoid the need for excessive support checking each time they are sent, and + * sending a hint for both CPU and GPU will count as two separate hints for the rate limiter. These + * hints should not be sent repeatedly for an ongoing expensive workload, as workload time reporting + * is intended to handle this. * + * @param session The {@link APerformanceHintSession} instance to send a hint for. * @param cpu Indicates if the workload reset is expected to affect the CPU. * @param gpu Indicates if the workload reset is expected to affect the GPU. - * @param debugName A required string used to identify this specific hint during - * tracing. This debug string will only be held for the duration of the - * method, and can be safely discarded after. + * @param identifier A required string used to distinguish this specific hint, using utf-8 encoding. + * This string will only be held for the duration of the method, and can be discarded after. * * @return 0 on success. - * EINVAL if no hints were requested. * EBUSY if the hint was rate limited. * EPIPE if communication with the system service has failed. - * ENOTSUP if the hint is not supported. */ int APerformanceHint_notifyWorkloadReset( APerformanceHintSession* _Nonnull session, - bool cpu, bool gpu, const char* _Nonnull debugName) __INTRODUCED_IN(36); + bool cpu, bool gpu, const char* _Nonnull identifier) __INTRODUCED_IN(36); /** - * Informs the framework of an upcoming one-off expensive frame for a graphics pipeline - * bound to this session. This frame will be treated as not representative of the workload as a - * whole, and it will be discarded the purposes of load tracking. The user can specify - * whether the workload spike is expected to be on the CPU, GPU, or both. + * Informs the framework of an upcoming one-off expensive workload cycle for a given session. + * This cycle will be treated as not representative of the workload as a whole, and it will be + * discarded the purposes of load tracking. The user can specify whether the workload spike is + * expected to be on the CPU, GPU, or both. * - * Sending hints for both CPU and GPU counts as two separate hints for the purposes of the - * rate limiter. + * These hints should be sent shortly before the start of the cycle where the workload is going to + * change, or as early as possible during that cycle for maximum effect. Hints sent towards the end + * of the cycle may be interpreted as applying to the next cycle. Any unsupported hints will be + * silently dropped, to avoid the need for excessive support checking each time they are sent, and + * sending a hint for both CPU and GPU will count as two separate hints for the rate limiter. These + * hints should not be sent repeatedly for an ongoing expensive workload, as workload time reporting + * is intended to handle this. * + * @param session The {@link APerformanceHintSession} instance to send a hint for. * @param cpu Indicates if the workload spike is expected to affect the CPU. * @param gpu Indicates if the workload spike is expected to affect the GPU. - * @param debugName A required string used to identify this specific hint during - * tracing. This debug string will only be held for the duration of the - * method, and can be safely discarded after. + * @param identifier A required string used to distinguish this specific hint, using utf-8 encoding. + * This string will only be held for the duration of the method, and can be discarded after. * * @return 0 on success. - * EINVAL if no hints were requested. * EBUSY if the hint was rate limited. * EPIPE if communication with the system service has failed. - * ENOTSUP if the hint is not supported. */ int APerformanceHint_notifyWorkloadSpike( APerformanceHintSession* _Nonnull session, - bool cpu, bool gpu, const char* _Nonnull debugName) __INTRODUCED_IN(36); + bool cpu, bool gpu, const char* _Nonnull identifier) __INTRODUCED_IN(36); /** * Associates a session with any {@link ASurfaceControl} or {@link ANativeWindow} - * instances managed by this session. + * instances managed by this session. Any previously associated objects that are not passed + * in again lose their association. Invalid or dead instances are ignored, and passing both + * lists as null drops all current associations. * * This method is primarily intended for sessions that manage the timing of an entire - * graphics pipeline end-to-end, such as those using the + * graphics pipeline end-to-end for frame pacing, such as those using the * {@link ASessionCreationConfig_setGraphicsPipeline} API. However, any session directly * or indirectly managing a graphics pipeline should still associate themselves with * directly relevant ASurfaceControl or ANativeWindow instances for better optimization. + * Additionally, if the surface associated with a session changes, this method should be called + * again to re-create the association. * - * To see any benefit from this method, the client must make sure they are updating the framerate + * To see any benefit from this method, the client must make sure they are updating the frame rate * of attached surfaces using methods such as {@link ANativeWindow_setFrameRate}, or by updating * any associated ASurfaceControls with transactions that have {ASurfaceTransaction_setFrameRate}. * @@ -407,16 +447,77 @@ int APerformanceHint_notifyWorkloadSpike( * * @return 0 on success. * EPIPE if communication has failed. - * ENOTSUP if unsupported. - * EINVAL if invalid or empty arguments passed. + * ENOTSUP if this is not supported on the device. */ int APerformanceHint_setNativeSurfaces(APerformanceHintSession* _Nonnull session, - ANativeWindow* _Nonnull* _Nullable nativeWindows, int nativeWindowsSize, - ASurfaceControl* _Nonnull* _Nullable surfaceControls, int surfaceControlsSize) + ANativeWindow* _Nonnull* _Nullable nativeWindows, size_t nativeWindowsSize, + ASurfaceControl* _Nonnull* _Nullable surfaceControls, size_t surfaceControlsSize) __INTRODUCED_IN(36); /** + * This enum represents different aspects of performance hint functionality. These can be passed + * to {@link APerformanceHint_isFeatureSupported} to determine whether the device exposes support + * for that feature. + * + * Some of these features will not expose failure to the client if used when unsupported, to prevent + * the client from needing to worry about handling different logic for each possible support + * configuration. The exception to this is features with important user-facing side effects, such as + * {@link APERF_HINT_AUTO_CPU} and {@link APERF_HINT_AUTO_GPU} modes which expect the client not to + * report durations while they are active. + */ +typedef enum APerformanceHintFeature : int32_t { + /** + * This value represents all APerformanceHintSession functionality. Using the Performance Hint + * API at all if this is not enabled will likely result in either + * {@link APerformanceHintManager} or {@link APerformanceHintSession} failing to create, or the + * session having little to no benefit even if creation succeeds. + */ + APERF_HINT_SESSIONS, + + /** + * This value represents the power efficiency mode, as exposed by + * {@link ASessionCreationConfig_setPreferPowerEfficiency} and + * {@link APerformanceHint_setPreferPowerEfficiency}. + */ + APERF_HINT_POWER_EFFICIENCY, + + /** + * This value the ability for sessions to bind to surfaces using + * {@link APerformanceHint_setNativeSurfaces} or + * {@link ASessionCreationConfig_setNativeSurfaces} + */ + APERF_HINT_SURFACE_BINDING, + + /** + * This value represents the "graphics pipeline" mode, as exposed by + * {@link ASessionCreationConfig_setGraphicsPipeline}. + */ + APERF_HINT_GRAPHICS_PIPELINE, + + /** + * This value represents the automatic CPU timing feature, as exposed by + * {@link ASessionCreationConfig_setUseAutoTiming}. + */ + APERF_HINT_AUTO_CPU, + + /** + * This value represents the automatic GPU timing feature, as exposed by + * {@link ASessionCreationConfig_setUseAutoTiming}. + */ + APERF_HINT_AUTO_GPU, +} APerformanceHintFeature; + +/** + * Checks whether the device exposes support for a specific feature. + * + * @param feature The specific feature enum to check. + * + * @return false if unsupported, true if supported. + */ +bool APerformanceHint_isFeatureSupported(APerformanceHintFeature feature) __INTRODUCED_IN(36); + +/** * Creates a new AWorkDuration. When the client finishes using {@link AWorkDuration}, it should * call {@link AWorkDuration_release()} to destroy {@link AWorkDuration} and release all resources * associated with it. @@ -478,8 +579,13 @@ void AWorkDuration_setActualGpuDurationNanos(AWorkDuration* _Nonnull aWorkDurati /** * Return the APerformanceHintSession wrapped by a Java PerformanceHintManager.Session object. * - * The Java session maintains ownership over the wrapped native session, so it cannot be - * closed using {@link APerformanceHint_closeSession}. + * The Java session maintains ownership over the wrapped native session, so it cannot be closed + * using {@link APerformanceHint_closeSession}. The return value is valid until the Java object + * containing this value dies. + * + * The returned pointer is intended to be used by JNI calls to access native performance APIs using + * a Java hint session wrapper, and then immediately discarded. Using the pointer after the death of + * the Java container results in undefined behavior. * * @param env The Java environment where the PerformanceHintManager.Session lives. * @param sessionObj The Java Session to unwrap. @@ -502,7 +608,6 @@ APerformanceHintSession* _Nonnull APerformanceHint_borrowSessionFromJava( ASessionCreationConfig* _Nonnull ASessionCreationConfig_create() __INTRODUCED_IN(36); - /** * Destroys a {@link ASessionCreationConfig} and frees all * resources associated with it. @@ -521,11 +626,8 @@ void ASessionCreationConfig_release( * @param tids The list of tids to be associated with this session. They must be part of * this process' thread group. * @param size The size of the list of tids. - * - * @return 0 on success. - * EINVAL if invalid array pointer or the value of size */ -int ASessionCreationConfig_setTids( +void ASessionCreationConfig_setTids( ASessionCreationConfig* _Nonnull config, const pid_t* _Nonnull tids, size_t size) __INTRODUCED_IN(36); @@ -534,15 +636,11 @@ int ASessionCreationConfig_setTids( * * @param config The {@link ASessionCreationConfig} * created by calling {@link ASessionCreationConfig_create()}. - * @param targetWorkDurationNanos The parameter to specify a target duration - * in nanoseconds for the new session; this value must be positive to use - * the work duration API. - * - * @return 0 on success. - * ENOTSUP if unsupported - * EINVAL if invalid value + * @param targetWorkDurationNanos The parameter to specify a target duration in nanoseconds for the + * new session; this value must be positive to use the work duration API, and may be ignored + * otherwise or set to zero. Negative values are invalid. */ -int ASessionCreationConfig_setTargetWorkDurationNanos( +void ASessionCreationConfig_setTargetWorkDurationNanos( ASessionCreationConfig* _Nonnull config, int64_t targetWorkDurationNanos) __INTRODUCED_IN(36); @@ -554,12 +652,8 @@ int ASessionCreationConfig_setTargetWorkDurationNanos( * @param config The {@link ASessionCreationConfig} * created by calling {@link ASessionCreationConfig_create()}. * @param enabled Whether power efficiency mode will be enabled. - * - * @return 0 on success. - * ENOTSUP if unsupported - * EINVAL if invalid pointer to creation config */ -int ASessionCreationConfig_setPreferPowerEfficiency( +void ASessionCreationConfig_setPreferPowerEfficiency( ASessionCreationConfig* _Nonnull config, bool enabled) __INTRODUCED_IN(36); /** @@ -569,24 +663,31 @@ int ASessionCreationConfig_setPreferPowerEfficiency( * buffer is fully finished drawing. * * It should include any threads on the critical path of that pipeline, - * up to a limit accessible from {@link getMaxGraphicsPipelineThreadsCount()}. + * up to a limit accessible from {@link APerformanceHint_getMaxGraphicsPipelineThreadsCount()}. * * @param config The {@link ASessionCreationConfig} * created by calling {@link ASessionCreationConfig_create()}. * @param enabled Whether this session manages a graphics pipeline's critical path. - * - * @return 0 on success. - * ENOTSUP if unsupported - * EINVAL if invalid pointer to creation config or maximum threads for graphics - pipeline is reached. */ -int ASessionCreationConfig_setGraphicsPipeline( +void ASessionCreationConfig_setGraphicsPipeline( ASessionCreationConfig* _Nonnull config, bool enabled) __INTRODUCED_IN(36); /** - * Associates a session with any {@link ASurfaceControl} or {@link ANativeWindow} - * instances managed by this session. See {@link APerformanceHint_setNativeSurfaces} - * for more details. + * Associates the created session with any {@link ASurfaceControl} or {@link ANativeWindow} + * instances it will be managing. Invalid or dead instances are ignored. + * + * This method is primarily intended for sessions that manage the timing of an entire + * graphics pipeline end-to-end for frame pacing, such as those using the + * {@link ASessionCreationConfig_setGraphicsPipeline} API. However, any session directly + * or indirectly managing a graphics pipeline should still associate themselves with + * directly relevant ASurfaceControl or ANativeWindow instances for better optimization. + * Additionally, if the surface associated with a session changes, this method should be called + * again to re-create the association. + * + * To see any benefit from this method, the client must make sure they are updating the frame rate + * of attached surfaces using methods such as {@link ANativeWindow_setFrameRate}, or by updating + * any associated ASurfaceControls with transactions that have {ASurfaceTransaction_setFrameRate}. + * * * @param config The {@link ASessionCreationConfig} * created by calling {@link ASessionCreationConfig_create()}. @@ -596,49 +697,46 @@ int ASessionCreationConfig_setGraphicsPipeline( * @param surfaceControls A pointer to a list of ASurfaceControls associated with this session. * nullptr can be passed to indicate there are no associated ASurfaceControls. * @param surfaceControlsSize The number of ASurfaceControls in the list. - * - * @return 0 on success. - * ENOTSUP if unsupported. - * EINVAL if invalid or empty arguments passed. */ -int ASessionCreationConfig_setNativeSurfaces( +void ASessionCreationConfig_setNativeSurfaces( ASessionCreationConfig* _Nonnull config, - ANativeWindow* _Nonnull* _Nullable nativeWindows, int nativeWindowsSize, - ASurfaceControl* _Nonnull* _Nullable surfaceControls, int surfaceControlsSize) + ANativeWindow* _Nonnull* _Nullable nativeWindows, size_t nativeWindowsSize, + ASurfaceControl* _Nonnull* _Nullable surfaceControls, size_t surfaceControlsSize) __INTRODUCED_IN(36); /** * Enable automatic timing mode for sessions using the GRAPHICS_PIPELINE API with an attached - * surface. In this mode, sessions do not need to report actual durations and only need - * to keep their thread list up-to-date, set a native surface, call - * {@link ASessionCreationConfig_setGraphicsPipeline()} to signal that the session is in - * "graphics pipeline" mode, and then set whether automatic timing is desired for the - * CPU, GPU, or both, using this method. + * surface. In this mode, sessions do not need to report timing data for the CPU, GPU, or both + * depending on the configuration. To use this mode, sessions should set a native surface + * using {@ASessionCreationConfig_setNativeSurfaces}, enable graphics pipeline mode with + * {@link ASessionCreationConfig_setGraphicsPipeline()}, and then call this method to set whether + * automatic timing is desired for the CPU, GPU, or both. Trying to enable this without also + * enabling the graphics pipeline mode will cause session creation to fail. * * It is still be beneficial to set an accurate target time, as this may help determine * timing information for some workloads where there is less information available from * the framework, such as games. Additionally, reported CPU durations will be ignored * while automatic CPU timing is enabled, and similarly GPU durations will be ignored * when automatic GPU timing is enabled. When both are enabled, the entire - * reportActualWorkDuration call will be ignored, and the session will be managed - * completely automatically. + * {@link APerformanceHint_reportActualWorkDuration} call will be ignored, and the session will be + * managed completely automatically. * - * This mode will not work unless the client makes sure they are updating the framerate - * of attached surfaces with methods such as {@link ANativeWindow_setFrameRate}, or updating - * any associated ASurfaceControls with transactions that have {ASurfaceTransaction_setFrameRate}. + * If the client is manually controlling their frame rate for those surfaces, then they must make + * sure they are updating the frame rate with {@link ANativeWindow_setFrameRate}, or updating any + * associated ASurfaceControls with transactions that have {ASurfaceTransaction_setFrameRate} set. + * + * The user of this API should ensure this feature is supported by checking + * {@link APERF_HINT_AUTO_CPU} and {@link APERF_HINT_AUTO_GPU} with + * {@link APerformanceHint_isFeatureSupported} and falling back to manual timing if it is not. + * Trying to use automatic timing when it is unsupported will cause session creation to fail. * * @param config The {@link ASessionCreationConfig} * created by calling {@link ASessionCreationConfig_create()}. * @param cpu Whether to enable automatic timing for the CPU for this session. * @param gpu Whether to enable automatic timing for the GPU for this session. - * - * @return 0 on success. - * ENOTSUP if unsupported. */ -int ASessionCreationConfig_setUseAutoTiming( - ASessionCreationConfig* _Nonnull config, - bool cpu, bool gpu) - __INTRODUCED_IN(36); +void ASessionCreationConfig_setUseAutoTiming( + ASessionCreationConfig* _Nonnull config, bool cpu, bool gpu) __INTRODUCED_IN(36); __END_DECLS 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 69620df16e..bdb1413555 100644 --- a/include/android/system_health.h +++ b/include/android/system_health.h @@ -16,6 +16,31 @@ /** * @defgroup SystemHealth +* + * SystemHealth provides access to data about how various system resources are used by applications. + * + * CPU/GPU headroom APIs are designed to be best used by applications with consistent and intense + * workload such as games to query the remaining capacity headroom over a short period and perform + * optimization accordingly. Due to the nature of the fast job scheduling and frequency scaling of + * CPU and GPU, the headroom by nature will have "TOCTOU" problem which makes it less suitable for + * apps with inconsistent or low workload to take any useful action but simply monitoring. And to + * avoid oscillation it's not recommended to adjust workload too frequent (on each polling request) + * or too aggressively. As the headroom calculation is more based on reflecting past history usage + * than predicting future capacity. Take game as an example, if the API returns CPU headroom of 0 in + * one scenario (especially if it's constant across multiple calls), or some value significantly + * smaller than other scenarios, then it can reason that the recent performance result is more CPU + * bottlenecked. Then reducing the CPU workload intensity can help reserve some headroom to handle + * the load variance better, which can result in less frame drops or smooth FPS value. On the other + * hand, if the API returns large CPU headroom constantly, the app can be more confident to increase + * the workload and expect higher possibility of device meeting its performance expectation. + * App can also use thermal APIs to read the current thermal status and headroom first, then poll + * the CPU and GPU headroom if the device is (about to) getting thermal throttled. If the CPU/GPU + * headrooms provide enough significance such as one valued at 0 while the other at 100, then it can + * be used to infer that reducing CPU workload could be more efficient to cool down the device. + * There is a caveat that the power controller may scale down the frequency of the CPU and GPU due + * to thermal and other reasons, which can result in a higher than usual percentage usage of the + * capacity. + * * @{ */ @@ -70,55 +95,40 @@ typedef struct ACpuHeadroomParams ACpuHeadroomParams; */ typedef struct AGpuHeadroomParams AGpuHeadroomParams; -/** - * Creates a new instance of ACpuHeadroomParams. - * - * When the client finishes using {@link ACpuHeadroomParams}, - * {@link ACpuHeadroomParams_destroy()} must be called to destroy - * and free up the resources associated with {@link ACpuHeadroomParams}. - * - * Available since API level 36. - * - * @return A new instance of ACpuHeadroomParams. - */ -ACpuHeadroomParams *_Nonnull ACpuHeadroomParams_create() -__INTRODUCED_IN(36); - -enum ACpuHeadroomCalculationType { +typedef enum ACpuHeadroomCalculationType : int32_t { /** - * Use the minimum headroom value within the calculation window. + * The headroom calculation type bases on minimum value over a specified window. * Introduced in API level 36. */ ACPU_HEADROOM_CALCULATION_TYPE_MIN = 0, /** - * Use the average headroom value within the calculation window. + * The headroom calculation type bases on average value over a specified window. * Introduced in API level 36. */ ACPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1, -}; -typedef enum ACpuHeadroomCalculationType ACpuHeadroomCalculationType; +} ACpuHeadroomCalculationType; -enum AGpuHeadroomCalculationType { +typedef enum AGpuHeadroomCalculationType : int32_t { /** - * Use the minimum headroom value within the calculation window. + * The headroom calculation type bases on minimum value over a specified window. * Introduced in API level 36. */ AGPU_HEADROOM_CALCULATION_TYPE_MIN = 0, /** - * Use the average headroom value within the calculation window. + * The headroom calculation type bases on average value over a specified window. * Introduced in API level 36. */ AGPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1, -}; -typedef enum AGpuHeadroomCalculationType AGpuHeadroomCalculationType; +} AGpuHeadroomCalculationType; /** - * Sets the headroom calculation window size in ACpuHeadroomParams. + * Sets the CPU headroom calculation window size in milliseconds. * * Available since API level 36. * * @param params The params to be set. - * @param windowMillis The window size in milliseconds ranged from [50, 10000]. The smaller the + * @param windowMillis The window size in milliseconds ranges from + * {@link ASystemHealth_getCpuHeadroomCalculationWindowRange}. The smaller the * window size, the larger fluctuation in the headroom value should be expected. * The default value can be retrieved from the * {@link #ACpuHeadroomParams_getCalculationWindowMillis} if not set. The device @@ -129,136 +139,210 @@ void ACpuHeadroomParams_setCalculationWindowMillis(ACpuHeadroomParams *_Nonnull __INTRODUCED_IN(36); /** - * Gets the headroom calculation window size in ACpuHeadroomParams. + * Gets the CPU headroom calculation window size in milliseconds. + * + * This will return the default value chosen by the device if not set. * * Available since API level 36. * - * @param params The params to be set. + * @param params The params to read from. * @return This will return the default value chosen by the device if the params is not set. */ -int ACpuHeadroomParams_getCalculationWindowMillis(ACpuHeadroomParams *_Nonnull params) +int ACpuHeadroomParams_getCalculationWindowMillis(ACpuHeadroomParams* _Nonnull params) __INTRODUCED_IN(36); /** - * Sets the headroom calculation window size in AGpuHeadroomParams. + * Sets the GPU headroom calculation window size in milliseconds. * * Available since API level 36. * * @param params The params to be set. - * @param windowMillis The window size in milliseconds ranged from [50, 10000]. The smaller the + * @param windowMillis The window size in milliseconds ranges from + * {@link ASystemHealth_getGpuHeadroomCalculationWindowRange}. The smaller the * window size, the larger fluctuation in the headroom value should be expected. * The default value can be retrieved from the * {@link #AGpuHeadroomParams_getCalculationWindowMillis} if not set. The device * will try to use the closest feasible window size to this param. */ -void AGpuHeadroomParams_setCalculationWindowMillis(AGpuHeadroomParams *_Nonnull params, +void AGpuHeadroomParams_setCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params, int windowMillis) __INTRODUCED_IN(36); /** - * Gets the headroom calculation window size in AGpuHeadroomParams. + * Gets the GPU headroom calculation window size in milliseconds. + * + * This will return the default value chosen by the device if not set. * * Available since API level 36. * - * @param params The params to be set. + * @param params The params to read from. * @return This will return the default value chosen by the device if the params is not set. */ -int AGpuHeadroomParams_getCalculationWindowMillis(AGpuHeadroomParams *_Nonnull params) +int AGpuHeadroomParams_getCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params) __INTRODUCED_IN(36); /** - * Sets the headroom calculation type in ACpuHeadroomParams. + * Sets the CPU headroom calculation type in {@link ACpuHeadroomParams}. * * Available since API level 36. * * @param params The params to be set. * @param calculationType The headroom calculation type. */ -void ACpuHeadroomParams_setCalculationType(ACpuHeadroomParams *_Nonnull params, +void ACpuHeadroomParams_setCalculationType(ACpuHeadroomParams* _Nonnull params, ACpuHeadroomCalculationType calculationType) __INTRODUCED_IN(36); /** - * Gets the headroom calculation type in ACpuHeadroomParams. + * Gets the CPU headroom calculation type in {@link ACpuHeadroomParams}. + * + * This will return the default value chosen by the device if not set. * * Available since API level 36. * - * @param params The params to be set. + * @param params The params to read from. * @return The headroom calculation type. */ ACpuHeadroomCalculationType -ACpuHeadroomParams_getCalculationType(ACpuHeadroomParams *_Nonnull params) +ACpuHeadroomParams_getCalculationType(ACpuHeadroomParams* _Nonnull params) __INTRODUCED_IN(36); /** - * Sets the headroom calculation type in AGpuHeadroomParams. + * Sets the GPU headroom calculation type in {@link AGpuHeadroomParams}. * * Available since API level 36. * * @param params The params to be set. * @param calculationType The headroom calculation type. */ -void AGpuHeadroomParams_setCalculationType(AGpuHeadroomParams *_Nonnull params, +void AGpuHeadroomParams_setCalculationType(AGpuHeadroomParams* _Nonnull params, AGpuHeadroomCalculationType calculationType) __INTRODUCED_IN(36); /** - * Gets the headroom calculation type in AGpuHeadroomParams. + * Gets the GPU headroom calculation type in {@link AGpuHeadroomParams}. + * + * This will return the default value chosen by the device if not set. * * Available since API level 36. * - * @param params The params to be set. + * @param params The params to read from. * @return The headroom calculation type. */ AGpuHeadroomCalculationType -AGpuHeadroomParams_getCalculationType(AGpuHeadroomParams *_Nonnull params) +AGpuHeadroomParams_getCalculationType(AGpuHeadroomParams* _Nonnull params) __INTRODUCED_IN(36); /** - * Sets the thread TIDs to track in ACpuHeadroomParams. + * Sets the thread TIDs to track in {@link ACpuHeadroomParams}. + * + * The TIDs should belong to the same of the process that will make the headroom call. And they + * should not have different core affinity. + * + * If not set or set to empty, the headroom will be based on the PID of the process making the call. * * Available since API level 36. * * @param params The params to be set. - * @param tids Non-null array of TIDs, maximum 5. + * @param tids Non-null array of TIDs, where maximum size can be read from + * {@link ASystemHealth_getMaxCpuHeadroomTidsSize}. * @param tidsSize The size of the tids array. */ -void ACpuHeadroomParams_setTids(ACpuHeadroomParams *_Nonnull params, const int *_Nonnull tids, - int tidsSize) +void ACpuHeadroomParams_setTids(ACpuHeadroomParams* _Nonnull params, const int* _Nonnull tids, + size_t tidsSize) __INTRODUCED_IN(36); /** - * Creates a new instance of AGpuHeadroomParams. + * Creates a new instance of {@link ACpuHeadroomParams}. + * + * When the client finishes using {@link ACpuHeadroomParams}, + * {@link ACpuHeadroomParams_destroy} must be called to destroy + * and free up the resources associated with {@link ACpuHeadroomParams}. + * + * Available since API level 36. + * + * @return A new instance of {@link ACpuHeadroomParams}. + */ +ACpuHeadroomParams* _Nonnull ACpuHeadroomParams_create(void) +__INTRODUCED_IN(36); + +/** + * Creates a new instance of {@link AGpuHeadroomParams}. * * When the client finishes using {@link AGpuHeadroomParams}, - * {@link AGpuHeadroomParams_destroy()} must be called to destroy + * {@link AGpuHeadroomParams_destroy} must be called to destroy * and free up the resources associated with {@link AGpuHeadroomParams}. * * Available since API level 36. * - * @return A new instance of AGpuHeadroomParams. + * @return A new instance of {@link AGpuHeadroomParams}. */ -AGpuHeadroomParams *_Nonnull AGpuHeadroomParams_create() +AGpuHeadroomParams* _Nonnull AGpuHeadroomParams_create(void) __INTRODUCED_IN(36); /** - * Deletes the ACpuHeadroomParams instance. + * Deletes the {@link ACpuHeadroomParams} instance. * * Available since API level 36. * * @param params The params to be deleted. */ -void ACpuHeadroomParams_destroy(ACpuHeadroomParams *_Nonnull params) +void ACpuHeadroomParams_destroy(ACpuHeadroomParams* _Nullable params) __INTRODUCED_IN(36); /** - * Deletes the AGpuHeadroomParams instance. + * Deletes the {@link AGpuHeadroomParams} instance. * * Available since API level 36. * * @param params The params to be deleted. */ -void AGpuHeadroomParams_destroy(AGpuHeadroomParams *_Nonnull params) +void AGpuHeadroomParams_destroy(AGpuHeadroomParams* _Nullable params) +__INTRODUCED_IN(36); + +/** + * Gets the maximum number of TIDs this device supports for getting CPU headroom. + * + * See {@link ACpuHeadroomParams_setTids}. + * + * Available since API level 36. + * + * @param outSize Non-null output pointer to the max size. + * @return 0 on success. + * ENOTSUP if the CPU headroom API is unsupported. + */ +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. + * @param outMaxMillis Non-null output pointer to be set to the maximum window size in milliseconds. + * @return 0 on success. + * ENOTSUP if API is unsupported. + */ +int ASystemHealth_getCpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis, + int32_t* _Nonnull outMaxMillis) +__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. + * @param outMaxMillis Non-null output pointer to be set to the maximum window size in milliseconds. + * @return 0 on success. + * ENOTSUP if API is unsupported. + */ +int ASystemHealth_getGpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis, + int32_t* _Nonnull outMaxMillis) __INTRODUCED_IN(36); /** @@ -269,21 +353,27 @@ __INTRODUCED_IN(36); * be used with the thermal status and headroom to determine if reducing the CPU bound workload can * help reduce the device temperature to avoid thermal throttling. * + * If the params are valid, each call will perform at least one synchronous binder transaction that + * can take more than 1ms. So it's not recommended to call or wait for this on critical threads. + * Some devices may implement this as an on-demand API with lazy initialization, so the caller + * should expect higher latency when making the first call (especially with non-default params) + * since app starts or after changing params, as the device may need to change its data collection. + * * Available since API level 36. * - * @param params The params to customize the CPU headroom calculation, or nullptr to use the default + * @param params The params to customize the CPU headroom calculation, or nullptr to use default. * @param outHeadroom Non-null output pointer to a single float, which will be set to the CPU * headroom value. The value will be a single value or `Float.NaN` if it's - * temporarily unavailable. + * temporarily unavailable due to server error or not enough user CPU workload. * Each valid value ranges from [0, 100], where 0 indicates no more cpu resources * can be granted. - * @return 0 on success + * @return 0 on success. * EPIPE if failed to get the CPU headroom. * EPERM if the TIDs do not belong to the same process. * ENOTSUP if API or requested params is unsupported. */ -int ASystemHealth_getCpuHeadroom(const ACpuHeadroomParams *_Nullable params, - float *_Nonnull outHeadroom) +int ASystemHealth_getCpuHeadroom(const ACpuHeadroomParams* _Nullable params, + float* _Nonnull outHeadroom) __INTRODUCED_IN(36); /** @@ -294,52 +384,58 @@ __INTRODUCED_IN(36); * be used with the thermal status and headroom to determine if reducing the GPU bound workload can * help reduce the device temperature to avoid thermal throttling. * + * If the params are valid, each call will perform at least one synchronous binder transaction that + * can take more than 1ms. So it's not recommended to call or wait for this on critical threads. + * Some devices may implement this as an on-demand API with lazy initialization, so the caller + * should expect higher latency when making the first call (especially with non-default params) + * since app starts or after changing params, as the device may need to change its data collection. + * * Available since API level 36 * - * @param params The params to customize the GPU headroom calculation, or nullptr to use the default + * @param params The params to customize the GPU headroom calculation, or nullptr to use default * @param outHeadroom Non-null output pointer to a single float, which will be set to the GPU * headroom value. The value will be a single value or `Float.NaN` if it's * temporarily unavailable. * Each valid value ranges from [0, 100], where 0 indicates no more gpu resources * can be granted. - * @return 0 on success + * @return 0 on success. * EPIPE if failed to get the GPU headroom. * ENOTSUP if API or requested params is unsupported. */ -int ASystemHealth_getGpuHeadroom(const AGpuHeadroomParams *_Nullable params, - float *_Nonnull outHeadroom) +int ASystemHealth_getGpuHeadroom(const AGpuHeadroomParams* _Nullable params, + float* _Nonnull outHeadroom) __INTRODUCED_IN(36); /** * Gets minimum polling interval for calling {@link ASystemHealth_getCpuHeadroom} in milliseconds. * - * The getCpuHeadroom API may return cached result if called more frequently than the interval. + * The {@link ASystemHealth_getCpuHeadroom} API may return cached result if called more frequently + * than the interval. * * Available since API level 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. + * @return 0 on success. * ENOTSUP if API is unsupported. */ -int ASystemHealth_getCpuHeadroomMinIntervalMillis(int64_t *_Nonnull outMinIntervalMillis) +int ASystemHealth_getCpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis) __INTRODUCED_IN(36); /** * Gets minimum polling interval for calling {@link ASystemHealth_getGpuHeadroom} in milliseconds. * - * The getGpuHeadroom API may return cached result if called more frequent than the interval. + * The {@link ASystemHealth_getGpuHeadroom} API may return cached result if called more frequently + * than the interval. * * Available since API level 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. + * @return 0 on success. * ENOTSUP if API is unsupported. */ -int ASystemHealth_getGpuHeadroomMinIntervalMillis(int64_t *_Nonnull outMinIntervalMillis) +int ASystemHealth_getGpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis) __INTRODUCED_IN(36); #ifdef __cplusplus 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/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/AccelerationCurve.h b/include/input/AccelerationCurve.h index 0cf648a2f7..8a4a5d429b 100644 --- a/include/input/AccelerationCurve.h +++ b/include/input/AccelerationCurve.h @@ -46,4 +46,15 @@ struct AccelerationCurveSegment { std::vector<AccelerationCurveSegment> createAccelerationCurveForPointerSensitivity( int32_t sensitivity); +/* + * Creates a flat acceleration curve for disabling pointer acceleration. + * + * This method generates a single AccelerationCurveSegment with specific values + * to effectively disable acceleration for both mice and touchpads. + * A flat acceleration curve ensures a constant gain, meaning that the output + * velocity is directly proportional to the input velocity, resulting in + * a 1:1 movement ratio between the input device and the on-screen pointer. + */ +std::vector<AccelerationCurveSegment> createFlatAccelerationCurve(int32_t sensitivity); + } // namespace android 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..3ae865a33a 100644 --- a/include/input/DisplayTopologyGraph.h +++ b/include/input/DisplayTopologyGraph.h @@ -42,8 +42,10 @@ 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; }; /** @@ -52,6 +54,7 @@ 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; }; } // 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..4b42f775dd --- /dev/null +++ b/include/input/InputFlags.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + 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/performance_hint_private.h b/include/private/performance_hint_private.h index e3f98badbe..a468313341 100644 --- a/include/private/performance_hint_private.h +++ b/include/private/performance_hint_private.h @@ -125,8 +125,10 @@ APerformanceHintSession* APerformanceHint_createSessionInternal(APerformanceHint /** * Creates a session using ASessionCreationConfig */ -APerformanceHintSession* APerformanceHint_createSessionUsingConfigInternal( - APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig, +int APerformanceHint_createSessionUsingConfigInternal( + APerformanceHintManager* manager, + ASessionCreationConfig* config, + APerformanceHintSession** sessionOut, SessionTag tag); /** 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/binder/Android.bp b/libs/binder/Android.bp index 9d9ae31ccf..ea5343a2a0 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 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 f7e0915f15..1c1b6f30a4 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -630,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()"); @@ -807,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 " @@ -844,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); @@ -1498,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; diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 9f5d822c55..777c22a63e 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -156,7 +156,7 @@ enum { #ifdef BINDER_WITH_KERNEL_IPC static void acquire_object(const sp<ProcessState>& proc, const flat_binder_object& obj, - const void* who) { + const void* who, bool tagFds) { switch (obj.hdr.type) { case BINDER_TYPE_BINDER: if (obj.binder) { @@ -173,7 +173,7 @@ static void acquire_object(const sp<ProcessState>& proc, const flat_binder_objec return; } case BINDER_TYPE_FD: { - if (obj.cookie != 0) { // owned + if (tagFds && obj.cookie != 0) { // owned FdTag(obj.handle, nullptr, who); } return; @@ -616,7 +616,7 @@ status_t Parcel::appendFrom(const Parcel* parcel, size_t offset, size_t len) { } } - acquire_object(proc, *flat, this); + acquire_object(proc, *flat, this, true /*tagFds*/); } } #else @@ -1800,13 +1800,22 @@ restart_write: // Need to write meta-data? if (nullMetaData || val.binder != 0) { kernelFields->mObjects[kernelFields->mObjectsSize] = mDataPos; - acquire_object(ProcessState::self(), val, this); + acquire_object(ProcessState::self(), val, this, true /*tagFds*/); kernelFields->mObjectsSize++; } return finishWrite(sizeof(flat_binder_object)); } + if (mOwner) { + // continueWrite does have the logic to convert this from an + // owned to an unowned Parcel. However, this is pretty inefficient, + // and it's really strange to need to do so, so prefer to avoid + // these paths than try to support them. + ALOGE("writing objects not supported on owned Parcels"); + return PERMISSION_DENIED; + } + if (!enoughData) { const status_t err = growData(sizeof(val)); if (err != NO_ERROR) return err; @@ -2723,6 +2732,65 @@ size_t Parcel::ipcObjectsCount() const return 0; } +static void do_nothing_release_func(const uint8_t* data, size_t dataSize, + const binder_size_t* objects, size_t objectsCount) { + (void)data; + (void)dataSize; + (void)objects; + (void)objectsCount; +} +static void delete_data_release_func(const uint8_t* data, size_t dataSize, + const binder_size_t* objects, size_t objectsCount) { + delete[] data; + (void)dataSize; + (void)objects; + (void)objectsCount; +} + +void Parcel::makeDangerousViewOf(Parcel* p) { + if (p->isForRpc()) { + // warning: this must match the logic in rpcSetDataReference + auto* rf = p->maybeRpcFields(); + LOG_ALWAYS_FATAL_IF(rf == nullptr); + std::vector<std::variant<binder::unique_fd, binder::borrowed_fd>> fds; + if (rf->mFds) { + fds.reserve(rf->mFds->size()); + for (const auto& fd : *rf->mFds) { + fds.push_back(binder::borrowed_fd(toRawFd(fd))); + } + } + status_t result = + rpcSetDataReference(rf->mSession, p->mData, p->mDataSize, + rf->mObjectPositions.data(), rf->mObjectPositions.size(), + std::move(fds), do_nothing_release_func); + LOG_ALWAYS_FATAL_IF(result != OK, "Failed: %s", statusToString(result).c_str()); + } else { +#ifdef BINDER_WITH_KERNEL_IPC + // warning: this must match the logic in ipcSetDataReference + auto* kf = p->maybeKernelFields(); + LOG_ALWAYS_FATAL_IF(kf == nullptr); + + // Ownership of FDs is passed to the Parcel from kernel binder. This should be refactored + // to move this ownership out of Parcel and into release_func. However, today, Parcel + // always assums it can own and close FDs today. So, for purposes of testing consistency, + // , create new FDs it can own. + + uint8_t* newData = new uint8_t[p->mDataSize]; // deleted by delete_data_release_func + memcpy(newData, p->mData, p->mDataSize); + for (size_t i = 0; i < kf->mObjectsSize; i++) { + flat_binder_object* flat = + reinterpret_cast<flat_binder_object*>(newData + kf->mObjects[i]); + if (flat->hdr.type == BINDER_TYPE_FD) { + flat->handle = fcntl(flat->handle, F_DUPFD_CLOEXEC, 0); + } + } + + ipcSetDataReference(newData, p->mDataSize, kf->mObjects, kf->mObjectsSize, + delete_data_release_func); +#endif // BINDER_WITH_KERNEL_IPC + } +} + void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, const binder_size_t* objects, size_t objectsCount, release_func relFunc) { // this code uses 'mOwner == nullptr' to understand whether it owns memory @@ -2733,6 +2801,7 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, const bin auto* kernelFields = maybeKernelFields(); LOG_ALWAYS_FATAL_IF(kernelFields == nullptr); // guaranteed by freeData. + // must match makeDangerousViewOf mData = const_cast<uint8_t*>(data); mDataSize = mDataCapacity = dataSize; kernelFields->mObjects = const_cast<binder_size_t*>(objects); @@ -2811,6 +2880,7 @@ status_t Parcel::rpcSetDataReference( auto* rpcFields = maybeRpcFields(); LOG_ALWAYS_FATAL_IF(rpcFields == nullptr); // guaranteed by markForRpc. + // must match makeDangerousViewOf mData = const_cast<uint8_t*>(data); mDataSize = mDataCapacity = dataSize; mOwner = relFunc; @@ -2878,15 +2948,17 @@ void Parcel::releaseObjects() #endif // BINDER_WITH_KERNEL_IPC } -void Parcel::acquireObjects() -{ +void Parcel::reacquireObjects(size_t objectsSize) { auto* kernelFields = maybeKernelFields(); if (kernelFields == nullptr) { return; } #ifdef BINDER_WITH_KERNEL_IPC - size_t i = kernelFields->mObjectsSize; + LOG_ALWAYS_FATAL_IF(objectsSize > kernelFields->mObjectsSize, + "Object size %zu out of range of %zu", objectsSize, + kernelFields->mObjectsSize); + size_t i = objectsSize; if (i == 0) { return; } @@ -2896,8 +2968,10 @@ void Parcel::acquireObjects() while (i > 0) { i--; const flat_binder_object* flat = reinterpret_cast<flat_binder_object*>(data + objects[i]); - acquire_object(proc, *flat, this); + acquire_object(proc, *flat, this, false /*tagFds*/); // they are already tagged } +#else + (void) objectsSize; #endif // BINDER_WITH_KERNEL_IPC } @@ -3114,12 +3188,8 @@ status_t Parcel::continueWrite(size_t desired) return NO_MEMORY; } - // Little hack to only acquire references on objects - // we will be keeping. - size_t oldObjectsSize = kernelFields->mObjectsSize; - kernelFields->mObjectsSize = objectsSize; - acquireObjects(); - kernelFields->mObjectsSize = oldObjectsSize; + // only acquire references on objects we are keeping + reacquireObjects(objectsSize); } if (rpcFields) { if (status_t status = truncateRpcObjects(objectsSize); status != OK) { 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/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/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h index 9ef4e694dd..f7465e2c1a 100644 --- a/libs/binder/include/binder/IPCThreadState.h +++ b/libs/binder/include/binder/IPCThreadState.h @@ -64,7 +64,10 @@ public: * Returns the PID of the process which has made the current binder * call. If not in a binder call, this will return getpid. * - * Warning: oneway transactions do not receive PID. Even if you expect + * Warning do not use this as a security identifier! PID is unreliable + * as it may be re-used. This should mostly be used for debugging. + * + * oneway transactions do not receive PID. Even if you expect * a transaction to be synchronous, a misbehaving client could send it * as an asynchronous call and result in a 0 PID here. Additionally, if * there is a race and the calling process dies, the PID may still be diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index 1154211582..6c4c6fe573 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -651,6 +651,11 @@ public: LIBBINDER_EXPORTED void print(std::ostream& to, uint32_t flags = 0) const; + // This API is to quickly become a view of another Parcel, so that we can also + // test 'owner' paths quickly. It's extremely dangerous to use this API in + // practice, and you should never ever do it. + LIBBINDER_EXPORTED void makeDangerousViewOf(Parcel* p); + private: // Close all file descriptors in the parcel at object positions >= newObjectsSize. void closeFileDescriptors(size_t newObjectsSize); @@ -666,7 +671,7 @@ private: void ipcSetDataReference(const uint8_t* data, size_t dataSize, const binder_size_t* objects, size_t objectsCount, release_func relFunc); // Takes ownership even when an error is returned. - status_t rpcSetDataReference( + [[nodiscard]] status_t rpcSetDataReference( const sp<RpcSession>& session, const uint8_t* data, size_t dataSize, const uint32_t* objectTable, size_t objectTableSize, std::vector<std::variant<binder::unique_fd, binder::borrowed_fd>>&& ancillaryFds, @@ -674,7 +679,7 @@ private: status_t finishWrite(size_t len); void releaseObjects(); - void acquireObjects(); + void reacquireObjects(size_t objectSize); status_t growData(size_t len); // Clear the Parcel and set the capacity to `desired`. // Doesn't reset the RPC session association. 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/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h index bd46c473b4..d69d318a28 100644 --- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h +++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h @@ -419,6 +419,9 @@ binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient * This can be used with higher-level system services to determine the caller's identity and check * permissions. * + * Warning do not use this as a security identifier! PID is unreliable as it may be re-used. This + * should mostly be used for debugging. + * * Available since API level 29. * * \return calling uid or the current process's UID if this thread isn't processing a transaction. 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/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/src/state.rs b/libs/binder/rust/src/state.rs index 145ae651d7..609334eb53 100644 --- a/libs/binder/rust/src/state.rs +++ b/libs/binder/rust/src/state.rs @@ -102,7 +102,10 @@ impl ThreadState { /// dies and is replaced with another process with elevated permissions and /// the same PID. /// - /// Warning: oneway transactions do not receive PID. Even if you expect + /// Warning: do not use this as a security identifier! PID is unreliable + /// as it may be re-used. This should mostly be used for debugging. + /// + /// oneway transactions do not receive PID. Even if you expect /// a transaction to be synchronous, a misbehaving client could send it /// as a synchronous call and result in a 0 PID here. Additionally, if /// there is a race and the calling process dies, the PID may still be diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp index a41726c313..b2ba1ae38d 100644 --- a/libs/binder/tests/parcel_fuzzer/binder.cpp +++ b/libs/binder/tests/parcel_fuzzer/binder.cpp @@ -121,6 +121,11 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS { PARCEL_READ_NO_STATUS(size_t, hasFileDescriptors), PARCEL_READ_NO_STATUS(std::vector<android::sp<android::IBinder>>, debugReadAllStrongBinders), PARCEL_READ_NO_STATUS(std::vector<int>, debugReadAllFileDescriptors), + [] (const ::android::Parcel& p, FuzzedDataProvider&) { + FUZZ_LOG() << "about to markSensitive"; + p.markSensitive(); + FUZZ_LOG() << "markSensitive done"; + }, [] (const ::android::Parcel& p, FuzzedDataProvider& provider) { std::string interface = provider.ConsumeRandomLengthString(); FUZZ_LOG() << "about to enforceInterface: " << interface; diff --git a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h index 2812da79fa..11fcb061f6 100644 --- a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h +++ b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h @@ -28,6 +28,9 @@ struct RandomParcelOptions { std::function<void(Parcel* p, FuzzedDataProvider& provider)> writeHeader; std::vector<sp<IBinder>> extraBinders; std::vector<binder::unique_fd> extraFds; + + // internal state owned by fillRandomParcel, for Parcel views + std::vector<std::unique_ptr<Parcel>> extraParcels; }; /** diff --git a/libs/binder/tests/parcel_fuzzer/main.cpp b/libs/binder/tests/parcel_fuzzer/main.cpp index 192f9d5dce..d06b2d9020 100644 --- a/libs/binder/tests/parcel_fuzzer/main.cpp +++ b/libs/binder/tests/parcel_fuzzer/main.cpp @@ -70,7 +70,7 @@ void doTransactFuzz(const char* backend, const sp<B>& binder, FuzzedDataProvider uint32_t code = provider.ConsumeIntegral<uint32_t>(); uint32_t flag = provider.ConsumeIntegral<uint32_t>(); - FUZZ_LOG() << "backend: " << backend; + FUZZ_LOG() << "doTransactFuzz backend: " << backend; RandomParcelOptions options; @@ -101,7 +101,7 @@ void doReadFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads, // since we are only using a byte to index CHECK_LE(reads.size(), 255u) << reads.size(); - FUZZ_LOG() << "backend: " << backend; + FUZZ_LOG() << "doReadFuzz backend: " << backend; FUZZ_LOG() << "input: " << HexString(p.data(), p.dataSize()); FUZZ_LOG() << "instructions: " << HexString(instructions.data(), instructions.size()); @@ -122,10 +122,15 @@ void doReadWriteFuzz(const char* backend, const std::vector<ParcelRead<P>>& read RandomParcelOptions options; P p; + // small amount of initial Parcel data, since fillRandomParcel uses makeDangerousViewOf + std::vector<uint8_t> parcelData = + provider.ConsumeBytes<uint8_t>(provider.ConsumeIntegralInRange<size_t>(0, 20)); + fillRandomParcel(&p, FuzzedDataProvider(parcelData.data(), parcelData.size()), &options); + // since we are only using a byte to index CHECK_LE(reads.size() + writes.size(), 255u) << reads.size(); - FUZZ_LOG() << "backend: " << backend; + FUZZ_LOG() << "doReadWriteFuzz backend: " << backend; while (provider.remaining_bytes() > 0) { uint8_t idx = provider.ConsumeIntegralInRange<uint8_t>(0, reads.size() + writes.size() - 1); diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp index 7c196142e8..61b9612ba5 100644 --- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp +++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp @@ -17,6 +17,7 @@ #include <fuzzbinder/random_parcel.h> #include <android-base/logging.h> +#include <binder/Functional.h> #include <binder/RpcSession.h> #include <binder/RpcTransportRaw.h> #include <fuzzbinder/random_binder.h> @@ -32,10 +33,39 @@ static void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider) { CHECK(OK == p->write(data.data(), data.size())); } -void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, RandomParcelOptions* options) { +void fillRandomParcel(Parcel* outputParcel, FuzzedDataProvider&& provider, + RandomParcelOptions* options) { CHECK_NE(options, nullptr); - if (provider.ConsumeBool()) { + const uint8_t fuzzerParcelOptions = provider.ConsumeIntegral<uint8_t>(); + const bool resultShouldBeView = fuzzerParcelOptions & 1; + const bool resultShouldBeRpc = fuzzerParcelOptions & 2; + const bool resultShouldMarkSensitive = fuzzerParcelOptions & 4; + + auto sensitivity_guard = binder::impl::make_scope_guard([&]() { + if (resultShouldMarkSensitive) { + outputParcel->markSensitive(); + } + }); + + Parcel* p; + if (resultShouldBeView) { + options->extraParcels.push_back(std::make_unique<Parcel>()); + // held for duration of test, so that view will be valid + p = options->extraParcels[options->extraParcels.size() - 1].get(); + } else { + p = outputParcel; // directly fill out the output Parcel + } + + // must be last guard, so outputParcel gets setup as view before + // other guards + auto viewify_guard = binder::impl::make_scope_guard([&]() { + if (resultShouldBeView) { + outputParcel->makeDangerousViewOf(p); + } + }); + + if (resultShouldBeRpc) { auto session = RpcSession::make(RpcTransportCtxFactoryRaw::make()); CHECK_EQ(OK, session->addNullDebuggingClient()); // Set the protocol version so that we don't crash if the session diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp index 0ed8a554ac..3cb628925c 100644 --- a/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp +++ b/libs/binder/tests/parcel_fuzzer/random_parcel_seeds.cpp @@ -281,9 +281,9 @@ void generateSeedsFromRecording(borrowed_fd fd, // This buffer holds the bytes which will be used for fillRandomParcel API std::vector<uint8_t> fillParcelBuffer; - // Don't take rpc path - uint8_t rpcBranch = 0; - impl::writeReversedBuffer(fillParcelBuffer, rpcBranch); + // Use all default options. + uint8_t parcelOptions = 0; + impl::writeReversedBuffer(fillParcelBuffer, parcelOptions); // Implicit branch on this path -> options->writeHeader(p, provider) uint8_t writeHeaderInternal = 0; 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/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 4874dbde9c..626581cc2a 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 { @@ -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::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::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..ac66362242 --- /dev/null +++ b/libs/graphicsenv/graphicsenv_flags.aconfig @@ -0,0 +1,9 @@ +package: "com.android.graphics.graphicsenv.flags" +container: "system" + +flag { + name: "feature_overrides" + namespace: "core_graphics" + description: "This flag controls the 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 452e48bb75..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> @@ -120,6 +121,9 @@ public: // 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..5ab31dbaba 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", diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 5e6de78553..fa971426a7 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 @@ -242,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()) { @@ -419,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, @@ -622,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); @@ -645,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; { @@ -855,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) { @@ -1022,7 +1015,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, @@ -1030,7 +1023,7 @@ void BLASTBufferQueue::mergeWithNextTransaction(SurfaceComposerClient::Transacti std::lock_guard _lock{mMutex}; if (mLastAcquiredFrameNumber >= frameNumber) { // Apply the transaction since we have already acquired the desired frame. - t->apply(); + t->setApplyToken(mApplyToken).apply(); } else { mPendingTransactions.emplace_back(frameNumber, *t); // Clear the transaction so it can't be applied elsewhere. @@ -1128,10 +1121,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(); }); } @@ -1185,7 +1178,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); } @@ -1225,6 +1218,7 @@ 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; @@ -1251,6 +1245,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 @@ -1342,6 +1344,17 @@ void BLASTBufferQueue::setApplyToken(sp<IBinder> applyToken) { mApplyToken = std::move(applyToken); } +void BLASTBufferQueue::setWaitForBufferReleaseCallback( + std::function<void(const nsecs_t)> callback) { + std::lock_guard _lock{mWaitForBufferReleaseMutex}; + mWaitForBufferReleaseCallback = std::move(callback); +} + +std::function<void(const nsecs_t)> BLASTBufferQueue::getWaitForBufferReleaseCallback() const { + std::lock_guard _lock{mWaitForBufferReleaseMutex}; + return mWaitForBufferReleaseCallback; +} + #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL) void BLASTBufferQueue::updateBufferReleaseProducer() { 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..1585aae45c 100644 --- a/libs/gui/BufferItemConsumer.cpp +++ b/libs/gui/BufferItemConsumer.cpp @@ -24,6 +24,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 +36,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) diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index b0f6e69115..f21ac18f3c 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -108,6 +108,15 @@ void BufferQueue::ProxyConsumerListener::onSetFrameRate(float frameRate, int8_t } #endif +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +void BufferQueue::ProxyConsumerListener::onSlotCountChanged(int slotCount) { + sp<ConsumerListener> listener(mConsumerListener.promote()); + if (listener != nullptr) { + listener->onSlotCountChanged(slotCount); + } +} +#endif + void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer, sp<IGraphicBufferConsumer>* outConsumer, bool consumerIsSurfaceFlinger) { @@ -116,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 9855b5bca4..270bfbdc64 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -341,9 +341,9 @@ status_t BufferQueueConsumer::detachBuffer(int slot) { return BAD_VALUE; } - if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { - BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", - slot, BufferQueueDefs::NUM_BUFFER_SLOTS); + const int totalSlotCount = mCore->getTotalSlotCountLocked(); + if (slot < 0 || slot >= totalSlotCount) { + BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isAcquired()) { BQ_LOGE("detachBuffer: slot %d is not owned by the consumer " @@ -477,44 +477,38 @@ 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); - if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS || - releaseFence == nullptr) { - BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot, - releaseFence.get()); + const int totalSlotCount = mCore->getTotalSlotCountLocked(); + if (slot < 0 || slot >= totalSlotCount) { + BQ_LOGE("releaseBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); 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); + if (releaseFence == nullptr) { + BQ_LOGE("releaseBuffer: slot %d fence %p NULL", slot, releaseFence.get()); + return BAD_VALUE; } -#endif sp<IProducerListener> listener; { // Autolock scope std::lock_guard<std::mutex> lock(mCore->mMutex); + const int totalSlotCount = mCore->getTotalSlotCountLocked(); + if (slot < 0 || slot >= totalSlotCount || releaseFence == nullptr) { + BQ_LOGE("releaseBuffer: slot %d out of range [0, %d) or fence %p NULL", slot, + totalSlotCount, releaseFence.get()); + return BAD_VALUE; + } + // If the frame number has changed because the buffer has been reallocated, // we can ignore this releaseBuffer for the old buffer. // Ignore this for the shared buffer where the frame number can easily @@ -661,6 +655,43 @@ status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) { return NO_ERROR; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +status_t BufferQueueConsumer::getReleasedBuffersExtended(std::vector<bool>* outSlotMask) { + ATRACE_CALL(); + + if (outSlotMask == nullptr) { + BQ_LOGE("getReleasedBuffersExtended: outSlotMask may not be NULL"); + return BAD_VALUE; + } + + std::lock_guard<std::mutex> lock(mCore->mMutex); + + if (mCore->mIsAbandoned) { + BQ_LOGE("getReleasedBuffersExtended: BufferQueue has been abandoned"); + return NO_INIT; + } + + const int totalSlotCount = mCore->getTotalSlotCountLocked(); + outSlotMask->resize(totalSlotCount); + for (int s = 0; s < totalSlotCount; ++s) { + (*outSlotMask)[s] = !mSlots[s].mAcquireCalled; + } + + // Remove from the mask queued buffers for which acquire has been called, + // since the consumer will not receive their buffer addresses and so must + // retain their cached information + BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin()); + while (current != mCore->mQueue.end()) { + if (current->mAcquireCalled) { + (*outSlotMask)[current->mSlot] = false; + } + ++current; + } + + return NO_ERROR; +} +#endif + status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width, uint32_t height) { ATRACE_CALL(); @@ -679,6 +710,28 @@ status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width, return NO_ERROR; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +status_t BufferQueueConsumer::allowUnlimitedSlots(bool allowUnlimitedSlots) { + ATRACE_CALL(); + BQ_LOGV("allowUnlimitedSlots: %d", allowUnlimitedSlots); + std::lock_guard<std::mutex> lock(mCore->mMutex); + + if (mCore->mIsAbandoned) { + BQ_LOGE("allowUnlimitedSlots: BufferQueue has been abandoned"); + return NO_INIT; + } + + if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { + BQ_LOGE("allowUnlimitedSlots: BufferQueue already connected"); + return INVALID_OPERATION; + } + + mCore->mAllowExtendedSlotCount = allowUnlimitedSlots; + + return OK; +} +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { ATRACE_CALL(); @@ -718,16 +771,23 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( int maxAcquiredBuffers) { ATRACE_FORMAT("%s(%d)", __func__, maxAcquiredBuffers); - if (maxAcquiredBuffers < 1 || - maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) { - BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", - maxAcquiredBuffers); - return BAD_VALUE; - } - sp<IConsumerListener> listener; { // Autolock scope std::unique_lock<std::mutex> lock(mCore->mMutex); + + // We reserve two slots in order to guarantee that the producer and + // consumer can run asynchronously. + int maxMaxAcquiredBuffers = +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mCore->getTotalSlotCountLocked() - 2; +#else + BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS; +#endif + if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > maxMaxAcquiredBuffers) { + BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", maxAcquiredBuffers); + return BAD_VALUE; + } + mCore->waitWhileAllocatingLocked(lock); if (mCore->mIsAbandoned) { diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp index 5a093995b4..6c79904475 100644 --- a/libs/gui/BufferQueueCore.cpp +++ b/libs/gui/BufferQueueCore.cpp @@ -38,6 +38,8 @@ #include <system/window.h> +#include <ui/BufferQueueDefs.h> + namespace android { // Macros for include BufferQueueCore information in log messages @@ -97,7 +99,11 @@ BufferQueueCore::BufferQueueCore() mConnectedProducerListener(), mBufferReleasedCbEnabled(false), mBufferAttachedCbEnabled(false), +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), +#else mSlots(), +#endif mQueue(), mFreeSlots(), mFreeBuffers(), @@ -111,6 +117,9 @@ BufferQueueCore::BufferQueueCore() mDefaultWidth(1), mDefaultHeight(1), mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN), +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mAllowExtendedSlotCount(false), +#endif mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS), mMaxAcquiredBufferCount(1), mMaxDequeuedBufferCount(1), @@ -221,6 +230,14 @@ void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const } } +int BufferQueueCore::getTotalSlotCountLocked() const { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + return mAllowExtendedSlotCount ? mMaxBufferCount : BufferQueueDefs::NUM_BUFFER_SLOTS; +#else + return BufferQueueDefs::NUM_BUFFER_SLOTS; +#endif +} + int BufferQueueCore::getMinUndequeuedBufferCountLocked() const { // If dequeueBuffer is allowed to error out, we don't have to add an // extra buffer. @@ -253,6 +270,26 @@ int BufferQueueCore::getMaxBufferCountLocked() const { return maxBufferCount; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +status_t BufferQueueCore::extendSlotCountLocked(int size) { + int previousSize = (int)mSlots.size(); + if (previousSize > size) { + return BAD_VALUE; + } + if (previousSize == size) { + return NO_ERROR; + } + + mSlots.resize(size); + for (int i = previousSize; i < size; i++) { + mUnusedSlots.push_back(i); + } + + mMaxBufferCount = size; + return NO_ERROR; +} +#endif + void BufferQueueCore::clearBufferSlotLocked(int slot) { BQ_LOGV("clearBufferSlotLocked: slot %d", slot); @@ -383,7 +420,7 @@ void BufferQueueCore::notifyBufferReleased() const { void BufferQueueCore::validateConsistencyLocked() const { static const useconds_t PAUSE_TIME = 0; int allocatedSlots = 0; - for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { + for (int slot = 0; slot < getTotalSlotCountLocked(); ++slot) { bool isInFreeSlots = mFreeSlots.count(slot) != 0; bool isInFreeBuffers = std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) != diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 2e7cef0847..5961b41478 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -40,6 +40,7 @@ #include <gui/TraceUtils.h> #include <private/gui/BufferQueueThreadState.h> +#include <utils/Errors.h> #include <utils/Log.h> #include <utils/Trace.h> @@ -108,9 +109,9 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { return NO_INIT; } - if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { - BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", - slot, BufferQueueDefs::NUM_BUFFER_SLOTS); + int maxSlot = mCore->getTotalSlotCountLocked(); + if (slot < 0 || slot >= maxSlot) { + BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", slot, maxSlot); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("requestBuffer: slot %d is not owned by the producer " @@ -123,6 +124,49 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { return NO_ERROR; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +status_t BufferQueueProducer::extendSlotCount(int size) { + ATRACE_CALL(); + + sp<IConsumerListener> listener; + { + std::lock_guard<std::mutex> lock(mCore->mMutex); + BQ_LOGV("extendSlotCount: size %d", size); + + if (mCore->mIsAbandoned) { + BQ_LOGE("extendSlotCount: BufferQueue has been abandoned"); + return NO_INIT; + } + + if (!mCore->mAllowExtendedSlotCount) { + BQ_LOGE("extendSlotCount: Consumer did not allow unlimited slots"); + return INVALID_OPERATION; + } + + int maxBeforeExtension = mCore->mMaxBufferCount; + + if (size == maxBeforeExtension) { + return NO_ERROR; + } + + if (size < maxBeforeExtension) { + return BAD_VALUE; + } + + if (status_t ret = mCore->extendSlotCountLocked(size); ret != OK) { + return ret; + } + listener = mCore->mConsumerListener; + } + + if (listener) { + listener->onSlotCountChanged(size); + } + + return NO_ERROR; +} +#endif + status_t BufferQueueProducer::setMaxDequeuedBufferCount( int maxDequeuedBuffers) { int maxBufferCount; @@ -170,9 +214,10 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount(int maxDequeuedBuffers, int bufferCount = mCore->getMinUndequeuedBufferCountLocked(); bufferCount += maxDequeuedBuffers; - if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { + if (bufferCount > mCore->getTotalSlotCountLocked()) { BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large " - "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); + "(max %d)", + bufferCount, mCore->getTotalSlotCountLocked()); return BAD_VALUE; } @@ -648,11 +693,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(); @@ -756,9 +801,9 @@ status_t BufferQueueProducer::detachBuffer(int slot) { return BAD_VALUE; } - if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { - BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", - slot, BufferQueueDefs::NUM_BUFFER_SLOTS); + const int totalSlotCount = mCore->getTotalSlotCountLocked(); + if (slot < 0 || slot >= totalSlotCount) { + BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { // TODO(http://b/140581935): This message is BQ_LOGW because it @@ -993,9 +1038,9 @@ status_t BufferQueueProducer::queueBuffer(int slot, return NO_INIT; } - if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { - BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", - slot, BufferQueueDefs::NUM_BUFFER_SLOTS); + const int totalSlotCount = mCore->getTotalSlotCountLocked(); + if (slot < 0 || slot >= totalSlotCount) { + BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("queueBuffer: slot %d is not owned by the producer " @@ -1239,9 +1284,9 @@ status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { return BAD_VALUE; } - if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { - BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, - BufferQueueDefs::NUM_BUFFER_SLOTS); + const int totalSlotCount = mCore->getTotalSlotCountLocked(); + if (slot < 0 || slot >= totalSlotCount) { + BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " @@ -1409,6 +1454,9 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, output->nextFrameNumber = mCore->mFrameCounter + 1; output->bufferReplaced = false; output->maxBufferCount = mCore->mMaxBufferCount; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + output->isSlotExpansionAllowed = mCore->mAllowExtendedSlotCount; +#endif if (listener != nullptr) { // Set up a death notification so that we can disconnect @@ -1416,7 +1464,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); @@ -1505,8 +1553,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 = @@ -1637,11 +1684,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 602bba8dab..0266a3f2e0 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -37,6 +37,8 @@ #include <private/gui/ComposerService.h> +#include <ui/BufferQueueDefs.h> + #include <log/log.h> #include <utils/Log.h> #include <utils/String8.h> @@ -59,7 +61,11 @@ static int32_t createProcessUniqueId() { return android_atomic_inc(&globalCounter); } -ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) : +ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) + : +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), +#endif mAbandoned(false), mConsumer(bufferQueue), mPrevFinalReleaseFence(Fence::NO_FENCE) { @@ -68,7 +74,12 @@ ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool c #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) ConsumerBase::ConsumerBase(bool controlledByApp, bool consumerIsSurfaceFlinger) - : mAbandoned(false), mPrevFinalReleaseFence(Fence::NO_FENCE) { + : +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), +#endif + mAbandoned(false), + mPrevFinalReleaseFence(Fence::NO_FENCE) { sp<IGraphicBufferProducer> producer; BufferQueue::createBufferQueue(&producer, &mConsumer, consumerIsSurfaceFlinger); mSurface = sp<Surface>::make(producer, controlledByApp); @@ -77,7 +88,11 @@ ConsumerBase::ConsumerBase(bool controlledByApp, bool consumerIsSurfaceFlinger) ConsumerBase::ConsumerBase(const sp<IGraphicBufferProducer>& producer, const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp) - : mAbandoned(false), + : +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), +#endif + mAbandoned(false), mConsumer(consumer), mSurface(sp<Surface>::make(producer, controlledByApp)), mPrevFinalReleaseFence(Fence::NO_FENCE) { @@ -101,9 +116,16 @@ void ConsumerBase::initialize(bool controlledByApp) { if (err != NO_ERROR) { CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)", strerror(-err), err); - } else { - mConsumer->setConsumerName(mName); + return; } + + mConsumer->setConsumerName(mName); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + if (err = mConsumer->allowUnlimitedSlots(true); err != NO_ERROR) { + CB_LOGE("ConsumerBase: error marking as allowed to have unlimited slots: %s (%d)", + strerror(-err), err); + } +#endif } ConsumerBase::~ConsumerBase() { @@ -130,7 +152,11 @@ int ConsumerBase::getSlotForBufferLocked(const sp<GraphicBuffer>& buffer) { } uint64_t id = buffer->getId(); - for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + for (int i = 0; i < (int)mSlots.size(); ++i) { +#else + for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { +#endif auto& slot = mSlots[i]; if (slot.mGraphicBuffer && slot.mGraphicBuffer->getId() == id) { return i; @@ -242,6 +268,15 @@ void ConsumerBase::onBuffersReleased() { return; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + std::vector<bool> mask; + mConsumer->getReleasedBuffersExtended(&mask); + for (size_t i = 0; i < mSlots.size(); i++) { + if (mask[i]) { + freeBufferLocked(i); + } + } +#else uint64_t mask = 0; mConsumer->getReleasedBuffers(&mask); for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { @@ -249,11 +284,23 @@ void ConsumerBase::onBuffersReleased() { freeBufferLocked(i); } } +#endif } void ConsumerBase::onSidebandStreamChanged() { } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +void ConsumerBase::onSlotCountChanged(int slotCount) { + CB_LOGV("onSlotCountChanged: %d", slotCount); + Mutex::Autolock lock(mMutex); + + if (slotCount > (int)mSlots.size()) { + mSlots.resize(slotCount); + } +} +#endif + void ConsumerBase::abandon() { CB_LOGV("abandon"); Mutex::Autolock lock(mMutex); @@ -270,7 +317,11 @@ void ConsumerBase::abandonLocked() { CB_LOGE("abandonLocked: ConsumerBase is abandoned!"); return; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + for (int i = 0; i < (int)mSlots.size(); ++i) { +#else for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { +#endif freeBufferLocked(i); } // disconnect from the BufferQueue @@ -334,6 +385,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) { @@ -387,6 +458,15 @@ status_t ConsumerBase::setMaxBufferCount(int bufferCount) { CB_LOGE("setMaxBufferCount: ConsumerBase is abandoned!"); return NO_INIT; } + +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + if (status_t err = mConsumer->allowUnlimitedSlots(false); err != NO_ERROR) { + CB_LOGE("ConsumerBase: error marking as not allowed to have unlimited slots: %s (%d)", + strerror(-err), err); + return err; + } +#endif + return mConsumer->setMaxBufferCount(bufferCount); } #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) @@ -400,7 +480,6 @@ status_t ConsumerBase::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers); } -#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) status_t ConsumerBase::setConsumerIsProtected(bool isProtected) { Mutex::Autolock lock(mMutex); if (mAbandoned) { @@ -409,7 +488,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); @@ -448,6 +526,15 @@ status_t ConsumerBase::discardFreeBuffers() { if (err != OK) { return err; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + std::vector<bool> mask; + mConsumer->getReleasedBuffersExtended(&mask); + for (int i = 0; i < (int)mSlots.size(); i++) { + if (mask[i]) { + freeBufferLocked(i); + } + } +#else uint64_t mask; mConsumer->getReleasedBuffers(&mask); for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { @@ -455,6 +542,8 @@ status_t ConsumerBase::discardFreeBuffers() { freeBufferLocked(i); } } +#endif + return OK; } @@ -585,9 +674,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; @@ -596,13 +689,20 @@ status_t ConsumerBase::releaseBufferLocked( // buffer on the same slot), the buffer producer is definitely no longer // tracking it. if (!stillTracking(slot, graphicBuffer)) { + CB_LOGV("releaseBufferLocked: Not tracking, exiting without calling releaseBuffer for " + "slot=%d/%" PRIu64, + slot, mSlots[slot].mFrameNumber); return OK; } 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); } @@ -615,7 +715,11 @@ status_t ConsumerBase::releaseBufferLocked( bool ConsumerBase::stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + if (slot < 0 || slot >= (int)mSlots.size()) { +#else if (slot < 0 || slot >= BufferQueue::NUM_BUFFER_SLOTS) { +#endif return false; } return (mSlots[slot].mGraphicBuffer != nullptr && 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/Flags.cpp b/libs/gui/Flags.cpp index 85ee2cddad..ee2802f706 100644 --- a/libs/gui/Flags.cpp +++ b/libs/gui/Flags.cpp @@ -29,6 +29,14 @@ sp<SurfaceType> surfaceToSurfaceType(const sp<Surface>& surface) { #endif } +ParcelableSurfaceType surfaceToParcelableSurfaceType(const sp<Surface>& surface) { +#if WB_LIBCAMERASERVICE_WITH_DEPENDENCIES + return view::Surface::fromSurface(surface); +#else + return surface->getIGraphicBufferProducer(); +#endif +} + sp<IGraphicBufferProducer> surfaceTypeToIGBP(const sp<SurfaceType>& surface) { #if WB_LIBCAMERASERVICE_WITH_DEPENDENCIES return surface->getIGraphicBufferProducer(); diff --git a/libs/gui/FrameRateUtils.cpp b/libs/gui/FrameRateUtils.cpp index 5c4879c1bd..1b2354e942 100644 --- a/libs/gui/FrameRateUtils.cpp +++ b/libs/gui/FrameRateUtils.cpp @@ -42,7 +42,7 @@ bool ValidateFrameRate(float frameRate, int8_t compatibility, int8_t changeFrame if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT && compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE && - compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE && + compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_AT_LEAST && (!privileged || (compatibility != ANATIVEWINDOW_FRAME_RATE_EXACT && compatibility != ANATIVEWINDOW_FRAME_RATE_NO_VOTE))) { diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index f2173cd740..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), @@ -119,6 +164,9 @@ GLConsumer::GLConsumer(uint32_t tex, uint32_t texTarget, bool useFenceSync, bool mTexTarget(texTarget), mEglDisplay(EGL_NO_DISPLAY), mEglContext(EGL_NO_CONTEXT), +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mEglSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), +#endif mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), mAttached(true) { GLC_LOGV("GLConsumer"); @@ -129,27 +177,29 @@ GLConsumer::GLConsumer(uint32_t tex, uint32_t texTarget, bool useFenceSync, bool } #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) -GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, - uint32_t texTarget, bool useFenceSync, bool isControlledByApp) : - ConsumerBase(bq, isControlledByApp), - mCurrentCrop(Rect::EMPTY_RECT), - mCurrentTransform(0), - mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), - mCurrentFence(Fence::NO_FENCE), - mCurrentTimestamp(0), - mCurrentDataSpace(HAL_DATASPACE_UNKNOWN), - mCurrentFrameNumber(0), - mDefaultWidth(1), - mDefaultHeight(1), - mFilteringEnabled(true), - mTexName(tex), - mUseFenceSync(useFenceSync), - mTexTarget(texTarget), - mEglDisplay(EGL_NO_DISPLAY), - mEglContext(EGL_NO_CONTEXT), - mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), - mAttached(true) -{ +GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, uint32_t texTarget, + bool useFenceSync, bool isControlledByApp) + : ConsumerBase(bq, isControlledByApp), + mCurrentCrop(Rect::EMPTY_RECT), + mCurrentTransform(0), + mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), + mCurrentFence(Fence::NO_FENCE), + mCurrentTimestamp(0), + mCurrentDataSpace(HAL_DATASPACE_UNKNOWN), + mCurrentFrameNumber(0), + mDefaultWidth(1), + mDefaultHeight(1), + mFilteringEnabled(true), + mTexName(tex), + mUseFenceSync(useFenceSync), + mTexTarget(texTarget), + mEglDisplay(EGL_NO_DISPLAY), + mEglContext(EGL_NO_CONTEXT), +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mEglSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), +#endif + mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), + mAttached(true) { GLC_LOGV("GLConsumer"); memcpy(mCurrentTransformMatrix, mtxIdentity.asArray(), @@ -176,6 +226,9 @@ GLConsumer::GLConsumer(uint32_t texTarget, bool useFenceSync, bool isControlledB mTexTarget(texTarget), mEglDisplay(EGL_NO_DISPLAY), mEglContext(EGL_NO_CONTEXT), +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mEglSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), +#endif mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), mAttached(false) { GLC_LOGV("GLConsumer"); @@ -204,6 +257,9 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget, mTexTarget(texTarget), mEglDisplay(EGL_NO_DISPLAY), mEglContext(EGL_NO_CONTEXT), +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mEglSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), +#endif mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), mAttached(false) { GLC_LOGV("GLConsumer"); @@ -322,7 +378,7 @@ status_t GLConsumer::releaseTexImage() { } if (mReleasedTexImage == nullptr) { - mReleasedTexImage = new EglImage(getDebugTexImageBuffer()); + mReleasedTexImage = sp<EglImage>::make(getDebugTexImageBuffer()); } mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; @@ -354,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(); @@ -389,24 +445,35 @@ 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; } -status_t GLConsumer::releaseBufferLocked(int buf, - sp<GraphicBuffer> graphicBuffer, - EGLDisplay display, EGLSyncKHR eglFence) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +void GLConsumer::onSlotCountChanged(int slotCount) { + ConsumerBase::onSlotCountChanged(slotCount); + + Mutex::Autolock lock(mMutex); + if (slotCount > (int)mEglSlots.size()) { + mEglSlots.resize(slotCount); + } +} +#endif + +#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) @@ -468,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); @@ -479,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; } } @@ -713,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) { @@ -722,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 @@ -751,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 f3bd90cffb..0000000000 --- a/libs/gui/IConsumerListener.cpp +++ /dev/null @@ -1,122 +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, - LAST = ON_FRAME_DETACHED, -}; - -} // 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"); - } -}; - -// 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); - } -} - -} // namespace android diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp deleted file mode 100644 index 282957b940..0000000000 --- a/libs/gui/IGraphicBufferConsumer.cpp +++ /dev/null @@ -1,234 +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 <gui/BufferItem.h> -#include <gui/IConsumerListener.h> - -#include <binder/Parcel.h> - -#include <ui/Fence.h> -#include <ui/GraphicBuffer.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, - LAST = DUMP_STATE, -}; - -} // 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); - } - - 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); - } - - 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); - } - } -} - -} // namespace android diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 09144806ee..1d1910eb08 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -81,6 +81,7 @@ enum { GET_LAST_QUEUED_BUFFER2, SET_FRAME_RATE, SET_ADDITIONAL_OPTIONS, + SET_MAX_BUFER_COUNT_EXTENDED, }; class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> @@ -103,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(); @@ -149,6 +150,20 @@ public: return result; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + status_t extendSlotCount(int size) override { + Parcel data, reply; + data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); + data.writeInt32(size); + status_t result = remote()->transact(SET_MAX_BUFER_COUNT_EXTENDED, data, &reply); + if (result != NO_ERROR) { + return result; + } + result = reply.readInt32(); + return result; + } +#endif + virtual status_t setAsyncMode(bool async) { Parcel data, reply; data.writeInterfaceToken( @@ -182,7 +197,7 @@ public: } *buf = reply.readInt32(); - *fence = new Fence(); + *fence = sp<Fence>::make(); result = reply.read(**fence); if (result != NO_ERROR) { fence->clear(); @@ -278,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(); @@ -287,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(); @@ -625,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); @@ -635,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); @@ -672,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); @@ -685,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); @@ -981,6 +996,14 @@ IMPLEMENT_HYBRID_META_INTERFACE(GraphicBufferProducer, // ---------------------------------------------------------------------- +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +status_t IGraphicBufferProducer::extendSlotCount(int size) { + // No-op for IGBP other than BufferQueue. + (void)size; + return INVALID_OPERATION; +} +#endif + status_t IGraphicBufferProducer::setLegacyBufferDrop(bool drop) { // No-op for IGBP other than BufferQueue. (void) drop; @@ -1209,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) { @@ -1227,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; @@ -1283,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); @@ -1582,6 +1605,15 @@ status_t BnGraphicBufferProducer::onTransact( return NO_ERROR; } #endif +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + case SET_MAX_BUFER_COUNT_EXTENDED: { + CHECK_INTERFACE(IGraphicBufferProducer, data, reply); + int size = data.readInt32(); + status_t result = extendSlotCount(size); + reply->writeInt32(result); + return NO_ERROR; + } +#endif } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/IGraphicBufferProducerFlattenables.cpp b/libs/gui/IGraphicBufferProducerFlattenables.cpp index 4e92a39973..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; @@ -128,7 +128,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten( constexpr size_t IGraphicBufferProducer::QueueBufferOutput::minFlattenedSize() { return sizeof(width) + sizeof(height) + sizeof(transformHint) + sizeof(numPendingBuffers) + sizeof(nextFrameNumber) + sizeof(bufferReplaced) + sizeof(maxBufferCount) + - sizeof(result); + sizeof(result) + sizeof(isSlotExpansionAllowed); } size_t IGraphicBufferProducer::QueueBufferOutput::getFlattenedSize() const { return minFlattenedSize() + frameTimestamps.getFlattenedSize(); @@ -152,6 +152,7 @@ status_t IGraphicBufferProducer::QueueBufferOutput::flatten( FlattenableUtils::write(buffer, size, nextFrameNumber); FlattenableUtils::write(buffer, size, bufferReplaced); FlattenableUtils::write(buffer, size, maxBufferCount); + FlattenableUtils::write(buffer, size, isSlotExpansionAllowed); status_t result = frameTimestamps.flatten(buffer, size, fds, count); if (result != NO_ERROR) { @@ -175,6 +176,7 @@ status_t IGraphicBufferProducer::QueueBufferOutput::unflatten( FlattenableUtils::read(buffer, size, nextFrameNumber); FlattenableUtils::read(buffer, size, bufferReplaced); FlattenableUtils::read(buffer, size, maxBufferCount); + FlattenableUtils::read(buffer, size, isSlotExpansionAllowed); status_t result = frameTimestamps.unflatten(buffer, size, fds, count); if (result != NO_ERROR) { @@ -226,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) { @@ -321,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; @@ -393,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/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..43855dadcd 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -66,6 +66,7 @@ layer_state_t::layer_state_t() mask(0), reserved(0), cornerRadius(0.0f), + clientDrawnCornerRadius(0.0f), backgroundBlurRadius(0), color(0), bufferTransform(0), @@ -140,6 +141,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); @@ -274,6 +276,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); @@ -596,6 +599,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; @@ -677,7 +684,7 @@ void layer_state_t::merge(const layer_state_t& other) { } if (other.what & eInputInfoChanged) { what |= eInputInfoChanged; - windowInfoHandle = new WindowInfoHandle(*other.windowInfoHandle); + windowInfoHandle = sp<WindowInfoHandle>::make(*other.windowInfoHandle); } if (other.what & eBackgroundColorChanged) { what |= eBackgroundColorChanged; @@ -809,6 +816,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) { @@ -993,13 +1001,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); } 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 e41f9bbf43..63dcfbcb9b 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -38,6 +38,7 @@ #include <utils/NativeHandle.h> #include <utils/Trace.h> +#include <ui/BufferQueueDefs.h> #include <ui/DynamicDisplayInfo.h> #include <ui/Fence.h> #include <ui/GraphicBuffer.h> @@ -98,7 +99,10 @@ Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controll : mGraphicBufferProducer(bufferProducer), #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) mSurfaceDeathListener(nullptr), -#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) +#endif +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mSlots(NUM_BUFFER_SLOTS), +#endif mCrop(Rect::EMPTY_RECT), mBufferAge(0), mGenerationNumber(0), @@ -192,7 +196,7 @@ void Surface::allocateBuffers() { status_t Surface::allowAllocation(bool allowAllocation) { return mGraphicBufferProducer->allowAllocation(allowAllocation); } -#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) +#endif status_t Surface::setGenerationNumber(uint32_t generation) { status_t result = mGraphicBufferProducer->setGenerationNumber(generation); @@ -505,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", @@ -658,7 +662,11 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { return result; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + if (buf < 0 || buf >= (int)mSlots.size()) { +#else if (buf < 0 || buf >= NUM_BUFFER_SLOTS) { +#endif ALOGE("dequeueBuffer: IGraphicBufferProducer returned invalid slot number %d", buf); android_errorWriteLog(0x534e4554, "36991414"); // SafetyNet logging return FAILED_TRANSACTION; @@ -757,7 +765,11 @@ status_t Surface::detachBuffer(const sp<GraphicBuffer>& buffer) { Mutex::Autolock lock(mMutex); uint64_t bufferId = buffer->getId(); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + for (int slot = 0; slot < (int)mSlots.size(); ++slot) { +#else for (int slot = 0; slot < Surface::NUM_BUFFER_SLOTS; ++slot) { +#endif auto& bufferSlot = mSlots[slot]; if (bufferSlot.buffer != nullptr && bufferSlot.buffer->getId() == bufferId) { bufferSlot.buffer = nullptr; @@ -840,7 +852,11 @@ int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) { return output.result; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + if (output.slot < 0 || output.slot >= (int)mSlots.size()) { +#else if (output.slot < 0 || output.slot >= NUM_BUFFER_SLOTS) { +#endif mGraphicBufferProducer->cancelBuffers(cancelBufferInputs, &cancelBufferOutputs); ALOGE("%s: IGraphicBufferProducer returned invalid slot number %d", __FUNCTION__, output.slot); @@ -963,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) { @@ -1001,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; } @@ -1027,7 +1043,11 @@ int Surface::getSlotFromBufferLocked( return BAD_VALUE; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + for (int i = 0; i < (int)mSlots.size(); i++) { +#else for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { +#endif if (mSlots[i].buffer != nullptr && mSlots[i].buffer->handle == buffer->handle) { return i; @@ -1058,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, @@ -2072,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); } @@ -2084,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 = @@ -2094,6 +2114,9 @@ int Surface::connect(int api, const sp<SurfaceListener>& listener, bool reportBu mDefaultHeight = output.height; mNextFrameNumber = output.nextFrameNumber; mMaxBufferCount = output.maxBufferCount; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + mIsSlotExpansionAllowed = output.isSlotExpansionAllowed; +#endif // Ignore transform hint if sticky transform is set or transform to display inverse flag is // set. Transform hint should be ignored if the client is expected to always submit buffers @@ -2190,7 +2213,11 @@ int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer, *outFence = Fence::NO_FENCE; } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + for (int i = 0; i < (int)mSlots.size(); i++) { +#else for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { +#endif if (mSlots[i].buffer != nullptr && mSlots[i].buffer->getId() == buffer->getId()) { if (mReportRemovedBuffers) { @@ -2292,8 +2319,35 @@ int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) { ALOGV("Surface::setMaxDequeuedBufferCount"); Mutex::Autolock lock(mMutex); - status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount( - maxDequeuedBuffers); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + if (maxDequeuedBuffers > BufferQueueDefs::NUM_BUFFER_SLOTS && !mIsSlotExpansionAllowed) { + return BAD_VALUE; + } + + int minUndequeuedBuffers = 0; + status_t err = mGraphicBufferProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, + &minUndequeuedBuffers); + if (err != OK) { + ALOGE("IGraphicBufferProducer::query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS) returned %s", + strerror(-err)); + return err; + } + + if (maxDequeuedBuffers > (int)mSlots.size()) { + int newSlotCount = minUndequeuedBuffers + maxDequeuedBuffers; + err = mGraphicBufferProducer->extendSlotCount(newSlotCount); + if (err != OK) { + ALOGE("IGraphicBufferProducer::extendSlotCount(%d) returned %s", newSlotCount, + strerror(-err)); + return err; + } + + mSlots.resize(newSlotCount); + } + err = mGraphicBufferProducer->setMaxDequeuedBufferCount(maxDequeuedBuffers); +#else + status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount(maxDequeuedBuffers); +#endif ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) " "returned %s", maxDequeuedBuffers, strerror(-err)); @@ -2501,7 +2555,11 @@ void Surface::freeAllBuffers() { ALOGE("%s: %zu buffers were freed while being dequeued!", __FUNCTION__, mDequeuedSlots.size()); } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + for (int i = 0; i < (int)mSlots.size(); i++) { +#else for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { +#endif mSlots[i].buffer = nullptr; } } @@ -2510,7 +2568,11 @@ status_t Surface::getAndFlushBuffersFromSlots(const std::vector<int32_t>& slots, std::vector<sp<GraphicBuffer>>* outBuffers) { ALOGV("Surface::getAndFlushBuffersFromSlots"); for (int32_t i : slots) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + if (i < 0 || i >= (int)mSlots.size()) { +#else if (i < 0 || i >= NUM_BUFFER_SLOTS) { +#endif ALOGE("%s: Invalid slotIndex: %d", __FUNCTION__, i); return BAD_VALUE; } @@ -2670,7 +2732,11 @@ status_t Surface::lock( newDirtyRegion.set(bounds); mDirtyRegion.clear(); Mutex::Autolock lock(mMutex); - for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) { +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + for (int i = 0; i < (int)mSlots.size(); i++) { +#else + for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { +#endif mSlots[i].dirtyRegion.clear(); } } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index be88b11b9c..bb7184f9db 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()); @@ -829,9 +830,7 @@ SurfaceComposerClient::Transaction::Transaction() { SurfaceComposerClient::Transaction::Transaction(const Transaction& other) : mId(other.mId), - mAnimation(other.mAnimation), - mEarlyWakeupStart(other.mEarlyWakeupStart), - mEarlyWakeupEnd(other.mEarlyWakeupEnd), + mFlags(other.mFlags), mMayContainBuffer(other.mMayContainBuffer), mDesiredPresentTime(other.mDesiredPresentTime), mIsAutoTimestamp(other.mIsAutoTimestamp), @@ -846,7 +845,7 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) void SurfaceComposerClient::Transaction::sanitize(int pid, int uid) { uint32_t permissions = LayerStatePermissions::getTransactionPermissions(pid, uid); - for (auto & [handle, composerState] : mComposerStates) { + for (auto& composerState : mComposerStates) { composerState.state.sanitize(permissions); } if (!mInputWindowCommands.empty() && @@ -868,9 +867,7 @@ 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 uint32_t flags = parcel->readUint32(); const int64_t desiredPresentTime = parcel->readInt64(); const bool isAutoTimestamp = parcel->readBool(); const bool logCallPoints = parcel->readBool(); @@ -883,7 +880,7 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel if (count > parcel->dataSize()) { return BAD_VALUE; } - SortedVector<DisplayState> displayStates; + Vector<DisplayState> displayStates; displayStates.setCapacity(count); for (size_t i = 0; i < count; i++) { DisplayState displayState; @@ -926,17 +923,14 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel if (count > parcel->dataSize()) { return BAD_VALUE; } - std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> composerStates; - composerStates.reserve(count); + Vector<ComposerState> composerStates; + composerStates.setCapacity(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; + composerStates.add(composerState); } InputWindowCommands inputWindowCommands; @@ -965,15 +959,13 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel // Parsing was successful. Update the object. mId = transactionId; - mAnimation = animation; - mEarlyWakeupStart = earlyWakeupStart; - mEarlyWakeupEnd = earlyWakeupEnd; + mFlags = flags; mDesiredPresentTime = desiredPresentTime; mIsAutoTimestamp = isAutoTimestamp; mFrameTimelineInfo = frameTimelineInfo; - mDisplayStates = displayStates; + mDisplayStates = std::move(displayStates); mListenerCallbacks = listenerCallbacks; - mComposerStates = composerStates; + mComposerStates = std::move(composerStates); mInputWindowCommands = inputWindowCommands; mApplyToken = applyToken; mUncacheBuffers = std::move(uncacheBuffers); @@ -996,9 +988,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->writeUint32(mFlags); parcel->writeInt64(mDesiredPresentTime); parcel->writeBool(mIsAutoTimestamp); parcel->writeBool(mLogCallPoints); @@ -1023,8 +1013,7 @@ 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); + for (auto const& composerState : mComposerStates) { composerState.write(*parcel); } @@ -1081,23 +1070,31 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr } 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); + 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) { + releaseBufferIfOverwriting(it->state); } - mComposerStates[handle].state.merge(composerState.state); + it->state.merge(otherState.state); + } else { + mComposerStates.add(otherState); } } for (auto const& state : other.mDisplayStates) { - ssize_t index = mDisplayStates.indexOf(state); - if (index < 0) { - mDisplayStates.add(state); + 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.editItemAt(static_cast<size_t>(index)).merge(state); + mDisplayStates.add(state); } } @@ -1131,8 +1128,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr mInputWindowCommands.merge(other.mInputWindowCommands); mMayContainBuffer |= other.mMayContainBuffer; - mEarlyWakeupStart = mEarlyWakeupStart || other.mEarlyWakeupStart; - mEarlyWakeupEnd = mEarlyWakeupEnd || other.mEarlyWakeupEnd; + mFlags |= other.mFlags; mApplyToken = other.mApplyToken; mergeFrameTimelineInfo(mFrameTimelineInfo, other.mFrameTimelineInfo); @@ -1154,15 +1150,13 @@ void SurfaceComposerClient::Transaction::clear() { mInputWindowCommands.clear(); mUncacheBuffers.clear(); mMayContainBuffer = false; - mAnimation = false; - mEarlyWakeupStart = false; - mEarlyWakeupEnd = false; mDesiredPresentTime = 0; mIsAutoTimestamp = true; mFrameTimelineInfo = {}; mApplyToken = nullptr; mMergedTransactionIds.clear(); mLogCallPoints = false; + mFlags = 0; } uint64_t SurfaceComposerClient::Transaction::getId() { @@ -1197,8 +1191,8 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { } size_t count = 0; - for (auto& [handle, cs] : mComposerStates) { - layer_state_t* s = &(mComposerStates[handle].state); + for (auto& cs : mComposerStates) { + layer_state_t* s = &cs.state; if (!(s->what & layer_state_t::eBufferChanged)) { continue; } else if (s->bufferData && @@ -1323,42 +1317,26 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay 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; + 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; + uint32_t wakeupFlags = ISurfaceComposer::eEarlyWakeupStart | ISurfaceComposer::eEarlyWakeupEnd; + if ((mFlags & wakeupFlags) == wakeupFlags) { + mFlags &= ~(wakeupFlags); } - if (mEarlyWakeupEnd && !mEarlyWakeupStart) { - flags |= ISurfaceComposer::eEarlyWakeupEnd; - } - sp<IBinder> applyToken = mApplyToken ? mApplyToken : getDefaultApplyToken(); sp<ISurfaceComposer> sf(ComposerService::getComposerService()); status_t binderStatus = - sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, + sf->setTransactionState(mFrameTimelineInfo, mComposerStates, mDisplayStates, mFlags, applyToken, mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp, mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId, mMergedTransactionIds); @@ -1379,7 +1357,7 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay return binderStatus; } -sp<IBinder> SurfaceComposerClient::Transaction::sApplyToken = new BBinder(); +sp<IBinder> SurfaceComposerClient::Transaction::sApplyToken = sp<BBinder>::make(); std::mutex SurfaceComposerClient::Transaction::sApplyTokenMutex; @@ -1437,9 +1415,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 +1438,34 @@ std::optional<gui::StalledTransactionInfo> SurfaceComposerClient::getStalledTran } void SurfaceComposerClient::Transaction::setAnimationTransaction() { - mAnimation = true; + mFlags |= ISurfaceComposer::eAnimation; } void SurfaceComposerClient::Transaction::setEarlyWakeupStart() { - mEarlyWakeupStart = true; + mFlags |= ISurfaceComposer::eEarlyWakeupStart; } void SurfaceComposerClient::Transaction::setEarlyWakeupEnd() { - mEarlyWakeupEnd = true; + 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; + 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; } - return &(mComposerStates[handle].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.add(s); + + return &mComposerStates.editItemAt(mComposerStates.size() - 1).state; } void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback( @@ -1695,6 +1675,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); @@ -1961,9 +1953,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 +1964,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; } @@ -2487,15 +2479,17 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setConte // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::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; - 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)); + mDisplayStates.add(s); + return mDisplayStates.editItemAt(mDisplayStates.size() - 1); } status_t SurfaceComposerClient::Transaction::setDisplaySurface(const sp<IBinder>& token, @@ -2689,9 +2683,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 +2701,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 +2712,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; } @@ -3293,10 +3289,17 @@ status_t SurfaceComposerClient::removeHdrLayerInfoListener( return statusTFromBinderStatus(status); } -status_t SurfaceComposerClient::setActivePictureListener( +status_t SurfaceComposerClient::addActivePictureListener( + const sp<gui::IActivePictureListener>& listener) { + binder::Status status = + ComposerServiceAIDL::getComposerService()->addActivePictureListener(listener); + return statusTFromBinderStatus(status); +} + +status_t SurfaceComposerClient::removeActivePictureListener( const sp<gui::IActivePictureListener>& listener) { binder::Status status = - ComposerServiceAIDL::getComposerService()->setActivePictureListener(listener); + ComposerServiceAIDL::getComposerService()->removeActivePictureListener(listener); return statusTFromBinderStatus(status); } 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/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/CaptureArgs.aidl b/libs/gui/aidl/android/gui/CaptureArgs.aidl index 4920344e0e..2bbed2b9d6 100644 --- a/libs/gui/aidl/android/gui/CaptureArgs.aidl +++ b/libs/gui/aidl/android/gui/CaptureArgs.aidl @@ -69,10 +69,5 @@ parcelable CaptureArgs { // exact colorspace is not an appropriate intermediate result. // Note that if the caller is requesting a specific dataspace, this hint does nothing. boolean hintForSeamlessTransition = false; - - // Allows the screenshot to attach a gainmap, which allows for a per-pixel - // transformation of the screenshot to another luminance range, typically - // mapping an SDR base image into HDR. - boolean attachGainmap = false; } diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index 8c19bbbba9..da47ee27ba 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -607,8 +607,14 @@ interface ISurfaceComposer { oneway void removeJankListener(int layerId, IJankListener listener, long afterVsync); /** - * Sets the listener used to monitor visible content that is being processed with picture + * Adds a listener used to monitor visible content that is being processed with picture * profiles. */ - oneway void setActivePictureListener(IActivePictureListener listener); + oneway void addActivePictureListener(IActivePictureListener listener); + + /** + * Removes a listener used to monitor visible content that is being processed with picture + * profiles. + */ + oneway void removeActivePictureListener(IActivePictureListener listener); } 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 07558aa49d..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; } @@ -144,13 +147,24 @@ public: */ void setTransactionHangCallback(std::function<void(const std::string&)> callback); void setApplyToken(sp<IBinder>); + + void setWaitForBufferReleaseCallback(std::function<void(const nsecs_t)> callback) + EXCLUDES(mWaitForBufferReleaseMutex); + std::function<void(const nsecs_t)> getWaitForBufferReleaseCallback() const + EXCLUDES(mWaitForBufferReleaseMutex); + virtual ~BLASTBufferQueue(); 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 @@ -186,6 +200,7 @@ private: sp<SurfaceControl> mSurfaceControl GUARDED_BY(mMutex); mutable std::mutex mMutex; + mutable std::mutex mWaitForBufferReleaseMutex; std::condition_variable mCallbackCV; // BufferQueue internally allows 1 more than @@ -201,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 @@ -286,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. @@ -324,6 +339,8 @@ private: std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex); + 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..0bfa7b222e 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 diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h index 0948c4d076..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; @@ -76,6 +76,9 @@ public: void onSetFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy) override; #endif +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + void onSlotCountChanged(int slotCount) override; +#endif private: // mConsumerListener is a weak reference to the IConsumerListener. This is // the raison d'etre of ProxyConsumerListener. diff --git a/libs/gui/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h index 6aa801ab86..ab1231ad6b 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 @@ -96,11 +96,26 @@ public: // This should be called from the onBuffersReleased() callback. virtual status_t getReleasedBuffers(uint64_t* outSlotMask); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + // getReleasedBuffers sets the values pointed to by outSlotMask to the bits + // indicating which buffer slots have been released by the BufferQueue + // but have not yet been released by the consumer. + // + // This should be called from the onBuffersReleased() callback when + // allowUnlimitedSlots has been called. + virtual status_t getReleasedBuffersExtended(std::vector<bool>* outSlotMask) override; +#endif + // setDefaultBufferSize is used to set the size of buffers returned by // dequeueBuffer when a width and height of zero is requested. Default // is 1x1. virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + // see IGraphicBufferConsumer::allowUnlimitedSlots + virtual status_t allowUnlimitedSlots(bool allowUnlimitedSlots) override; +#endif + // see IGraphicBufferConsumer::setMaxBufferCount virtual status_t setMaxBufferCount(int bufferCount); @@ -152,6 +167,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. @@ -161,6 +177,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/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h index 77cdf2c9f3..7f92a46053 100644 --- a/libs/gui/include/gui/BufferQueueCore.h +++ b/libs/gui/include/gui/BufferQueueCore.h @@ -32,10 +32,11 @@ #include <utils/Trace.h> #include <utils/Vector.h> +#include <condition_variable> #include <list> -#include <set> #include <mutex> -#include <condition_variable> +#include <set> +#include <vector> #define ATRACE_BUFFER_INDEX(index) \ do { \ @@ -91,6 +92,10 @@ private: // Dump our state in a string void dumpState(const String8& prefix, String8* outResult) const; + // getTotalSlotCountLocked returns the total number of slots in use by the + // buffer queue at this time. + int getTotalSlotCountLocked() const; + // getMinUndequeuedBufferCountLocked returns the minimum number of buffers // that must remain in a state other than DEQUEUED. The async parameter // tells whether we're in asynchronous mode. @@ -120,6 +125,10 @@ private: int getMaxBufferCountLocked(bool asyncMode, bool dequeueBufferCannotBlock, int maxBufferCount) const; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + // This resizes mSlots to the given size, but only if it's increasing. + status_t extendSlotCountLocked(int size); +#endif // clearBufferSlotLocked frees the GraphicBuffer and sync resources for the // given slot. void clearBufferSlotLocked(int slot); @@ -204,7 +213,7 @@ private: // mConnectedProducerListener will not trigger onBufferAttached() callback. bool mBufferAttachedCbEnabled; - // mSlots is an array of buffer slots that must be mirrored on the producer + // mSlots is a collection of buffer slots that must be mirrored on the producer // side. This allows buffer ownership to be transferred between the producer // and consumer without sending a GraphicBuffer over Binder. The entire // array is initialized to NULL at construction time, and buffers are @@ -266,8 +275,14 @@ private: // is specified. android_dataspace mDefaultBufferDataSpace; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + // mAllowExtendedSlotCount is set by the consumer to permit the producer to + // request an unlimited number of slots. + bool mAllowExtendedSlotCount; +#endif + // mMaxBufferCount is the limit on the number of buffers that will be - // allocated at one time. This limit can be set by the consumer. + // allocated at one time. int mMaxBufferCount; // mMaxAcquiredBufferCount is the number of buffers that the consumer may diff --git a/libs/gui/include/gui/BufferQueueDefs.h b/libs/gui/include/gui/BufferQueueDefs.h index ffafb49615..42cf439450 100644 --- a/libs/gui/include/gui/BufferQueueDefs.h +++ b/libs/gui/include/gui/BufferQueueDefs.h @@ -17,6 +17,7 @@ #ifndef ANDROID_GUI_BUFFERQUEUECOREDEFS_H #define ANDROID_GUI_BUFFERQUEUECOREDEFS_H +#include <com_android_graphics_libgui_flags.h> #include <gui/BufferSlot.h> #include <ui/BufferQueueDefs.h> @@ -24,7 +25,11 @@ namespace android { class BufferQueueCore; namespace BufferQueueDefs { - typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS]; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + typedef std::vector<BufferSlot> SlotsType; +#else + typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS]; +#endif } // namespace BufferQueueDefs } // namespace android diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h index 086ce7ce56..50abadb922 100644 --- a/libs/gui/include/gui/BufferQueueProducer.h +++ b/libs/gui/include/gui/BufferQueueProducer.h @@ -47,6 +47,11 @@ public: // flags indicating that previously-returned buffers are no longer valid. virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + // see IGraphicsBufferProducer::extendSlotCount + virtual status_t extendSlotCount(int size) override; +#endif + // see IGraphicsBufferProducer::setMaxDequeuedBufferCount virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers); 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 e976aa48be..477d98df10 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; @@ -185,7 +185,9 @@ protected: virtual void onFrameDetached(const uint64_t bufferId) override; virtual void onBuffersReleased() override; virtual void onSidebandStreamChanged() override; - +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + virtual void onSlotCountChanged(int slotCount) override; +#endif virtual int getSlotForBufferLocked(const sp<GraphicBuffer>& buffer); virtual status_t detachBufferLocked(int slotIndex); @@ -243,10 +245,13 @@ 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 // returns true iff the slot still has the graphicBuffer in it. bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer); @@ -284,7 +289,11 @@ protected: // slot that has not yet been used. The buffer allocated to a slot will also // be replaced if the requested buffer usage or geometry differs from that // of the buffer allocated to a slot. +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + std::vector<Slot> mSlots; +#else Slot mSlots[BufferQueueDefs::NUM_BUFFER_SLOTS]; +#endif // mAbandoned indicates that the BufferQueue will no longer be used to // consume images buffers pushed to it using the IGraphicBufferProducer 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/Flags.h b/libs/gui/include/gui/Flags.h index 845bc54c71..446841bcd2 100644 --- a/libs/gui/include/gui/Flags.h +++ b/libs/gui/include/gui/Flags.h @@ -46,6 +46,7 @@ typedef android::sp<android::IGraphicBufferProducer> ParcelableSurfaceType; namespace flagtools { sp<SurfaceType> surfaceToSurfaceType(const sp<Surface>& surface); +ParcelableSurfaceType surfaceToParcelableSurfaceType(const sp<Surface>& surface); ParcelableSurfaceType toParcelableSurfaceType(const view::Surface& surface); sp<IGraphicBufferProducer> surfaceTypeToIGBP(const sp<SurfaceType>& surface); bool isSurfaceTypeValid(const sp<SurfaceType>& surface); diff --git a/libs/gui/include/gui/GLConsumer.h b/libs/gui/include/gui/GLConsumer.h index 8a66dc0cf1..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); @@ -266,8 +280,12 @@ protected: virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, uint64_t maxFrameNumber = 0) override; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + virtual void onSlotCountChanged(int slotCount) override; +#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; @@ -276,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, @@ -465,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 @@ -496,8 +514,11 @@ private: // slot that has not yet been used. The buffer allocated to a slot will also // be replaced if the requested buffer usage or geometry differs from that // of the buffer allocated to a slot. +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + std::vector<EglSlot> mEglSlots; +#else EglSlot mEglSlots[BufferQueueDefs::NUM_BUFFER_SLOTS]; - +#endif // mCurrentTexture is the buffer slot index of the buffer that is currently // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT, // indicating that no buffer slot is currently bound to the texture. Note, diff --git a/libs/gui/include/gui/IConsumerListener.h b/libs/gui/include/gui/IConsumerListener.h index 51d3959de7..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> @@ -98,27 +95,18 @@ public: virtual void onSetFrameRate(float /*frameRate*/, int8_t /*compatibility*/, int8_t /*changeFrameRateStrategy*/) {} #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; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + // Notifies the consumer that IGraphicBufferProducer::extendSlotCount has + // been called and the total slot count has increased. + // + // This will only ever be called if + // IGraphicBufferConsumer::allowUnlimitedSlots has been called on the + // consumer. + virtual void onSlotCountChanged(int /* slotCount */) {} +#endif }; -#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 18f5488173..8272a591da 100644 --- a/libs/gui/include/gui/IGraphicBufferConsumer.h +++ b/libs/gui/include/gui/IGraphicBufferConsumer.h @@ -16,6 +16,7 @@ #pragma once +#include <com_android_graphics_libgui_flags.h> #include <gui/OccupancyTracker.h> #include <binder/IInterface.h> @@ -35,15 +36,12 @@ class Fence; class GraphicBuffer; class IConsumerListener; class NativeHandle; -#ifndef NO_BINDER -class IGraphicBufferConsumer : public IInterface { -public: - DECLARE_META_INTERFACE(GraphicBufferConsumer) -#else + +/* + * See IGraphicBufferProducer for details on SLOT_COUNT. + */ 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. @@ -92,7 +90,7 @@ public: // // Return of a value other than NO_ERROR means an error has occurred: // * BAD_VALUE - the given slot number is invalid, either because it is out of the range - // [0, NUM_BUFFER_SLOTS) or because the slot it refers to is not + // [0, SLOT_COUNT) or because the slot it refers to is not // currently acquired. virtual status_t detachBuffer(int slot) = 0; @@ -134,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, @@ -173,6 +176,19 @@ public: // * NO_INIT - the BufferQueue has been abandoned. virtual status_t getReleasedBuffers(uint64_t* slotMask) = 0; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + // getReleasedBuffersExtended for each slot, sets slotMask[slot] to 1 if it + // corresponds to a released buffer slot. In particular, a released buffer + // is one that has been released by the BufferQueue but has not yet been + // released by the consumer. + // + // This should be called from the onBuffersReleased() callback. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the BufferQueue has been abandoned. + virtual status_t getReleasedBuffersExtended(std::vector<bool>* slotMask) = 0; +#endif + // setDefaultBufferSize is used to set the size of buffers returned by dequeueBuffer when a // width and height of zero is requested. Default is 1x1. // @@ -180,6 +196,26 @@ public: // * BAD_VALUE - either w or h was zero virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) = 0; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + // allowUnlimitedSlots allows the producer to set the upper bound on slots. + // + // Must be called before the producer is connected. If the producer + // increases the slot count, an IConsumerListener::onSlotCountChanged + // update is sent. + // + // This can not be used with setMaxBufferCount. Calls after + // setMaxBufferCount will fail and calls to setMaxBufferCount after setting + // this to true will fail. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the BufferQueue has been abandoned + // * INVALID_OPERATION - one of the following errors has occurred: + // * Producer has been connected + // * setMaxBufferCount has been called and shrunk the + // BufferQueue. + virtual status_t allowUnlimitedSlots(bool allowUnlimitedSlots) = 0; +#endif + // setMaxBufferCount sets the maximum value for the number of buffers used in the BufferQueue // (the initial default is NUM_BUFFER_SLOTS). If a call to setMaxAcquiredBufferCount (by the // consumer), or a call to setAsyncMode or setMaxDequeuedBufferCount (by the producer), would @@ -279,18 +315,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/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h index a42ddc466c..7accca6298 100644 --- a/libs/gui/include/gui/IGraphicBufferProducer.h +++ b/libs/gui/include/gui/IGraphicBufferProducer.h @@ -72,6 +72,14 @@ using HGraphicBufferProducerV2_0 = * dequeueBuffer() to get an empty buffer, fills it with data, then * calls queueBuffer() to make it available to the consumer. * + * BufferQueues have a size, which we'll refer to in other comments as + * SLOT_COUNT. Its default is 64 (NUM_BUFFER_SLOTS). It can be adjusted by + * the IGraphicBufferConsumer::setMaxBufferCount, or when + * IGraphicBufferConsumer::allowUnlimitedSlots is set to true, by + * IGraphicBufferProducer::extendSlotCount. The actual number of buffers in use + * is a function of various configurations, including whether we're in single + * buffer mode, the maximum dequeuable/aquirable buffers, and SLOT_COUNT. + * * This class was previously called ISurfaceTexture. */ #ifndef NO_BINDER @@ -106,7 +114,7 @@ public: // slot->buffer mapping so that it's not necessary to transfer a // GraphicBuffer for every dequeue operation. // - // The slot must be in the range of [0, NUM_BUFFER_SLOTS). + // The slot must be in the range of [0, SLOT_COUNT). // // Return of a value other than NO_ERROR means an error has occurred: // * NO_INIT - the buffer queue has been abandoned or the producer is not @@ -116,6 +124,30 @@ public: // * buffer specified by the slot is not dequeued virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + // extendSlotCount sets the maximum slot count (SLOT_COUNT) to the given + // size. This feature must be enabled by the consumer to function via + // IGraphicBufferConsumer::allowUnlimitedSlots. This must be called before + // the producer connects. + // + // After calling this, any slot can be returned in the [0, size) range. + // Callers are responsible for the allocation of the appropriate slots + // array for their own buffer cache. + // + // On success, the consumer is notified (so that it can increase its own + // slot cache). + // + // Return of a value other than NO_ERROR means that an error has occurred: + // * NO_INIT - the buffer queue has been abandoned + // * INVALID_OPERATION - one of the following conditions has occurred: + // * The producer is connected already + // * The consumer didn't call allowUnlimitedSlots + // * BAD_VALUE - The value is smaller than the previous max size + // (initialized to 64, then whatever the last call to this + // was) + virtual status_t extendSlotCount(int size); +#endif + // setMaxDequeuedBufferCount sets the maximum number of buffers that can be // dequeued by the producer at one time. If this method succeeds, any new // buffer slots will be both unallocated and owned by the BufferQueue object @@ -129,7 +161,7 @@ public: // will result in a BAD_VALUE error. // // The buffer count should be at least 1 (inclusive), but at most - // (NUM_BUFFER_SLOTS - the minimum undequeued buffer count) (exclusive). The + // (SLOT_COUNT - the minimum undequeued buffer count) (exclusive). The // minimum undequeued buffer count can be obtained by calling // query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS). // @@ -239,8 +271,8 @@ public: // * NO_INIT - the buffer queue has been abandoned or the producer is not // connected. // * BAD_VALUE - the given slot number is invalid, either because it is - // out of the range [0, NUM_BUFFER_SLOTS), or because the slot - // it refers to is not currently dequeued and requested. + // out of the range [0, SLOT_COUNT), or because the slot it + // refers to is not currently dequeued and requested. virtual status_t detachBuffer(int slot) = 0; // detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer, @@ -415,6 +447,7 @@ public: FrameEventHistoryDelta frameTimestamps; bool bufferReplaced{false}; int maxBufferCount{BufferQueueDefs::NUM_BUFFER_SLOTS}; + bool isSlotExpansionAllowed{false}; status_t result{NO_ERROR}; }; @@ -430,7 +463,7 @@ public: // below). Any other properties (zero point, etc) // are client-dependent, and should be documented by the client. // - // The slot must be in the range of [0, NUM_BUFFER_SLOTS). + // The slot must be in the range of [0, SLOT_COUNT). // // Upon success, the output will be filled with meaningful values // (refer to the documentation below). @@ -460,7 +493,7 @@ public: // // The buffer is not queued for use by the consumer. // - // The slot must be in the range of [0, NUM_BUFFER_SLOTS). + // The slot must be in the range of [0, SLOT_COUNT). // // The buffer will not be overwritten until the fence signals. The fence // will usually be the one obtained from dequeueBuffer. diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 1c31e46cb4..c2680a42dc 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -231,6 +231,7 @@ struct layer_state_t { eBufferReleaseChannelChanged = 0x40000'00000000, ePictureProfileHandleChanged = 0x80000'00000000, eAppContentPriorityChanged = 0x100000'00000000, + eClientDrawnCornerRadiusChanged = 0x200000'00000000, }; layer_state_t(); @@ -251,9 +252,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 +275,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,6 +301,11 @@ 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); @@ -328,6 +334,7 @@ struct layer_state_t { uint8_t reserved; matrix22_t matrix; float cornerRadius; + float clientDrawnCornerRadius; uint32_t backgroundBlurRadius; sp<SurfaceControl> relativeLayerSurfaceControl; @@ -425,7 +432,7 @@ struct layer_state_t { PictureProfileHandle pictureProfileHandle{PictureProfileHandle::NONE}; // A value indicating the significance of the layer's content to the app's desired user - // experience. A lower priority will result in more likelihood of getting access to limited + // experience. A higher value will result in more likelihood of getting access to limited // resources, such as picture processing hardware. int32_t appContentPriority = 0; @@ -495,12 +502,18 @@ 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); }; 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/Surface.h b/libs/gui/include/gui/Surface.h index 14a351316d..755674d9e6 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -558,7 +558,11 @@ protected: // slot that has not yet been used. The buffer allocated to a slot will also // be replaced if the requested buffer usage or geometry differs from that // of the buffer allocated to a slot. +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + std::vector<BufferSlot> mSlots; +#else BufferSlot mSlots[NUM_BUFFER_SLOTS]; +#endif // mReqWidth is the buffer width that will be requested at the next dequeue // operation. It is initialized to 1. @@ -732,6 +736,10 @@ protected: std::vector<sp<GraphicBuffer>> mRemovedBuffers; int mMaxBufferCount; +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + bool mIsSlotExpansionAllowed; +#endif + sp<IProducerListener> mListenerProxy; // Get and flush the buffers of given slots, if the buffer in the slot diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 0ce0c0a9c3..60f16ae902 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -298,7 +298,9 @@ public: static status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener); - static status_t setActivePictureListener(const sp<gui::IActivePictureListener>& listener); + static status_t addActivePictureListener(const sp<gui::IActivePictureListener>& listener); + + static status_t removeActivePictureListener(const sp<gui::IActivePictureListener>& listener); /* * Sends a power boost to the composer. This function is asynchronous. @@ -453,8 +455,8 @@ public: bool mLogCallPoints = false; protected: - std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> mComposerStates; - SortedVector<DisplayState> mDisplayStates; + Vector<ComposerState> mComposerStates; + Vector<DisplayState> mDisplayStates; std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash> mListenerCallbacks; std::vector<client_cache_t> mUncacheBuffers; @@ -465,10 +467,7 @@ public: std::vector<uint64_t> mMergedTransactionIds; uint64_t mId; - - bool mAnimation = false; - bool mEarlyWakeupStart = false; - bool mEarlyWakeupEnd = false; + uint32_t mFlags = 0; // 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 @@ -565,6 +564,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, @@ -616,7 +620,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/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h index eb3be5588a..420dc2103f 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. diff --git a/libs/gui/include/gui/mock/GraphicBufferConsumer.h b/libs/gui/include/gui/mock/GraphicBufferConsumer.h index 98f24c2d44..24d26b12a1 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,18 +26,24 @@ 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)); diff --git a/libs/gui/libgui_flags.aconfig b/libs/gui/libgui_flags.aconfig index 6bf38c05f1..90d91ac06a 100644 --- a/libs/gui/libgui_flags.aconfig +++ b/libs/gui/libgui_flags.aconfig @@ -138,4 +138,15 @@ flag { description: "Remove BufferQueueProducer::dequeue's wait on this fence (or the fence entirely) to prevent deadlocks" bug: "339705065" is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } } # 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 diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp index f07747f32f..87051a7aac 100644 --- a/libs/gui/tests/Android.bp +++ b/libs/gui/tests/Android.bp @@ -55,6 +55,7 @@ cc_test { "-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_BQ_EXTENDEDALLOCATE=true", "-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_WB_CONSUMER_BASE_OWNS_BQ=true", "-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_WB_PLATFORM_API_IMPROVEMENTS=true", + "-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_WB_UNLIMITED_SLOTS=true", ], srcs: [ 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 3b6a66efe9..b980f882ff 100644 --- a/libs/gui/tests/BufferItemConsumer_test.cpp +++ b/libs/gui/tests/BufferItemConsumer_test.cpp @@ -22,8 +22,11 @@ #include <gui/BufferItemConsumer.h> #include <gui/IProducerListener.h> #include <gui/Surface.h> +#include <ui/BufferQueueDefs.h> #include <ui/GraphicBuffer.h> +#include <unordered_set> + namespace android { static constexpr int kWidth = 100; @@ -57,14 +60,17 @@ class BufferItemConsumerTest : public ::testing::Test { }; void SetUp() override { - mBIC = new BufferItemConsumer(kUsage, kMaxLockedBuffers, true); + mBuffers.resize(BufferQueueDefs::NUM_BUFFER_SLOTS); + + 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, @@ -137,6 +143,11 @@ class BufferItemConsumerTest : public ::testing::Test { ASSERT_EQ(NO_ERROR, ret); } + void DetachBuffer(int slot) { + ALOGD("detachBuffer: slot=%d", slot); + status_t ret = mBIC->detachBuffer(mBuffers[slot]); + ASSERT_EQ(NO_ERROR, ret); + } std::mutex mMutex; int mFreedBufferCount{0}; @@ -146,7 +157,7 @@ class BufferItemConsumerTest : public ::testing::Test { sp<BufferFreedListener> mBFL; sp<IGraphicBufferProducer> mProducer; sp<IGraphicBufferConsumer> mConsumer; - sp<GraphicBuffer> mBuffers[BufferQueueDefs::NUM_BUFFER_SLOTS]; + std::vector<sp<GraphicBuffer>> mBuffers; }; // Test that detaching buffer from consumer side triggers onBufferFreed. @@ -239,4 +250,52 @@ TEST_F(BufferItemConsumerTest, DetachBufferWithBuffer) { } #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +TEST_F(BufferItemConsumerTest, UnlimitedSlots_AcquireReleaseAll) { + ASSERT_EQ(OK, mProducer->extendSlotCount(256)); + mBuffers.resize(256); + + ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(100)); + + std::unordered_set<int> slots; + for (int i = 0; i < 100; i++) { + int slot; + DequeueBuffer(&slot); + slots.insert(slot); + } + EXPECT_EQ(100u, slots.size()); + + for (int dequeuedSlot : slots) { + QueueBuffer(dequeuedSlot); + + int slot; + AcquireBuffer(&slot); + ReleaseBuffer(slot); + } +} + +TEST_F(BufferItemConsumerTest, UnlimitedSlots_AcquireDetachAll) { + ASSERT_EQ(OK, mProducer->extendSlotCount(256)); + mBuffers.resize(256); + + ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(100)); + + std::unordered_set<int> slots; + for (int i = 0; i < 100; i++) { + int slot; + DequeueBuffer(&slot); + slots.insert(slot); + } + EXPECT_EQ(100u, slots.size()); + + for (int dequeuedSlot : slots) { + QueueBuffer(dequeuedSlot); + + int slot; + AcquireBuffer(&slot); + DetachBuffer(slot); + } +} +#endif + } // namespace android diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 16060990bd..cfbb2e7386 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -20,6 +20,8 @@ #include "Constants.h" #include "MockConsumer.h" +#include <EGL/egl.h> + #include <gui/BufferItem.h> #include <gui/BufferItemConsumer.h> #include <gui/BufferQueue.h> @@ -30,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> @@ -43,8 +46,11 @@ #include <gmock/gmock.h> #include <gtest/gtest.h> +#include <csignal> #include <future> +#include <optional> #include <thread> +#include <unordered_map> #include <com_android_graphics_libgui_flags.h> @@ -61,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, @@ -95,6 +110,7 @@ protected: sp<IGraphicBufferProducer> mProducer; sp<IGraphicBufferConsumer> mConsumer; + std::vector<std::function<void()>> mTeardownFns; }; static const uint32_t TEST_DATA = 0x12345678u; @@ -102,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); @@ -119,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)); @@ -159,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) { @@ -1612,4 +1653,221 @@ TEST_F(BufferQueueTest, PassesThroughPictureProfileHandle) { } } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +struct MockUnlimitedSlotConsumer : public MockConsumer { + virtual void onSlotCountChanged(int size) override { mSize = size; } + + std::optional<int> mSize; +}; + +TEST_F(BufferQueueTest, UnlimitedSlots_FailsWhenNotAllowed) { + createBufferQueue(); + + sp<MockUnlimitedSlotConsumer> mc = sp<MockUnlimitedSlotConsumer>::make(); + EXPECT_EQ(OK, mConsumer->consumerConnect(mc, false)); + + EXPECT_EQ(INVALID_OPERATION, mProducer->extendSlotCount(64)); + EXPECT_EQ(INVALID_OPERATION, mProducer->extendSlotCount(32)); + EXPECT_EQ(INVALID_OPERATION, mProducer->extendSlotCount(128)); + + EXPECT_EQ(std::nullopt, mc->mSize); +} + +TEST_F(BufferQueueTest, UnlimitedSlots_OnlyAllowedForExtensions) { + createBufferQueue(); + + sp<MockUnlimitedSlotConsumer> consumerListener = sp<MockUnlimitedSlotConsumer>::make(); + EXPECT_EQ(OK, mConsumer->consumerConnect(consumerListener, false)); + EXPECT_EQ(OK, mConsumer->allowUnlimitedSlots(true)); + + EXPECT_EQ(BAD_VALUE, mProducer->extendSlotCount(32)); + EXPECT_EQ(OK, mProducer->extendSlotCount(64)); + EXPECT_EQ(OK, mProducer->extendSlotCount(128)); + EXPECT_EQ(128, *consumerListener->mSize); + + EXPECT_EQ(OK, mProducer->extendSlotCount(128)); + EXPECT_EQ(BAD_VALUE, mProducer->extendSlotCount(127)); +} + +class BufferQueueUnlimitedTest : public BufferQueueTest { +protected: + static constexpr auto kMaxBufferCount = 128; + static constexpr auto kAcquirableBufferCount = 2; + static constexpr auto kDequeableBufferCount = kMaxBufferCount - kAcquirableBufferCount; + + virtual void SetUp() override { + BufferQueueTest::SetUp(); + + createBufferQueue(); + setUpConsumer(); + setUpProducer(); + } + + void setUpConsumer() { + EXPECT_EQ(OK, mConsumer->consumerConnect(mConsumerListener, false)); + +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + EXPECT_EQ(OK, mConsumer->allowUnlimitedSlots(true)); +#endif + EXPECT_EQ(OK, mConsumer->setConsumerUsageBits(GraphicBuffer::USAGE_SW_READ_OFTEN)); + EXPECT_EQ(OK, mConsumer->setDefaultBufferSize(10, 10)); + EXPECT_EQ(OK, mConsumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888)); + EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(kAcquirableBufferCount)); + } + + void setUpProducer() { + EXPECT_EQ(OK, mProducer->extendSlotCount(kMaxBufferCount)); + + IGraphicBufferProducer::QueueBufferOutput output; + EXPECT_EQ(OK, + mProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, + /*producerControlledByApp*/ true, &output)); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) + ASSERT_TRUE(output.isSlotExpansionAllowed); +#endif + ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(kDequeableBufferCount)); + ASSERT_EQ(OK, mProducer->allowAllocation(true)); + } + + std::unordered_map<int, sp<Fence>> dequeueAll() { + std::unordered_map<int, sp<Fence>> slotsToFences; + + for (int i = 0; i < kDequeableBufferCount; ++i) { + int slot; + sp<Fence> fence; + sp<GraphicBuffer> buffer; + + status_t ret = + mProducer->dequeueBuffer(&slot, &fence, /*w*/ 0, /*h*/ 0, /*format*/ 0, + /*uint64_t*/ 0, + /*outBufferAge*/ nullptr, /*outTimestamps*/ nullptr); + if (ret & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) { + EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer)) + << "Unable to request buffer for slot " << slot; + } + EXPECT_FALSE(slotsToFences.contains(slot)); + slotsToFences.emplace(slot, fence); + } + EXPECT_EQ(kDequeableBufferCount, (int)slotsToFences.size()); + return slotsToFences; + } + + sp<MockUnlimitedSlotConsumer> mConsumerListener = sp<MockUnlimitedSlotConsumer>::make(); + sp<StubProducerListener> mProducerListener = sp<StubProducerListener>::make(); +}; + +TEST_F(BufferQueueUnlimitedTest, ExpandOverridesConsumerMaxBuffers) { + createBufferQueue(); + setUpConsumer(); + EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10)); + + setUpProducer(); + + EXPECT_EQ(kDequeableBufferCount, (int)dequeueAll().size()); +} + +TEST_F(BufferQueueUnlimitedTest, CanDetachAll) { + auto slotsToFences = dequeueAll(); + for (auto& [slot, fence] : slotsToFences) { + EXPECT_EQ(OK, mProducer->detachBuffer(slot)); + } +} + +TEST_F(BufferQueueUnlimitedTest, CanCancelAll) { + auto slotsToFences = dequeueAll(); + for (auto& [slot, fence] : slotsToFences) { + EXPECT_EQ(OK, mProducer->cancelBuffer(slot, fence)); + } +} + +TEST_F(BufferQueueUnlimitedTest, CanAcquireAndReleaseAll) { + auto slotsToFences = dequeueAll(); + for (auto& [slot, fence] : slotsToFences) { + IGraphicBufferProducer::QueueBufferInput input; + input.fence = fence; + + IGraphicBufferProducer::QueueBufferOutput output; + EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); + + BufferItem buffer; + EXPECT_EQ(OK, mConsumer->acquireBuffer(&buffer, 0)); + EXPECT_EQ(OK, + mConsumer->releaseBuffer(buffer.mSlot, buffer.mFrameNumber, EGL_NO_DISPLAY, + EGL_NO_SYNC, buffer.mFence)); + } +} + +TEST_F(BufferQueueUnlimitedTest, CanAcquireAndDetachAll) { + auto slotsToFences = dequeueAll(); + for (auto& [slot, fence] : slotsToFences) { + IGraphicBufferProducer::QueueBufferInput input; + input.fence = fence; + + IGraphicBufferProducer::QueueBufferOutput output; + EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); + + BufferItem buffer; + EXPECT_EQ(OK, mConsumer->acquireBuffer(&buffer, 0)); + EXPECT_EQ(OK, mConsumer->detachBuffer(buffer.mSlot)); + } +} + +TEST_F(BufferQueueUnlimitedTest, GetReleasedBuffersExtended) { + // First, acquire and release all the buffers so the consumer "knows" about + // them + auto slotsToFences = dequeueAll(); + + std::vector<bool> releasedSlots; + EXPECT_EQ(OK, mConsumer->getReleasedBuffersExtended(&releasedSlots)); + for (auto& [slot, _] : slotsToFences) { + EXPECT_TRUE(releasedSlots[slot]) + << "Slots that haven't been acquired will show up as released."; + } + for (auto& [slot, fence] : slotsToFences) { + IGraphicBufferProducer::QueueBufferInput input; + input.fence = fence; + + IGraphicBufferProducer::QueueBufferOutput output; + EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); + + BufferItem buffer; + EXPECT_EQ(OK, mConsumer->acquireBuffer(&buffer, 0)); + EXPECT_EQ(OK, + mConsumer->releaseBuffer(buffer.mSlot, buffer.mFrameNumber, EGL_NO_DISPLAY, + EGL_NO_SYNC_KHR, buffer.mFence)); + } + + EXPECT_EQ(OK, mConsumer->getReleasedBuffersExtended(&releasedSlots)); + for (auto& [slot, _] : slotsToFences) { + EXPECT_FALSE(releasedSlots[slot]) + << "Slots that have been acquired will show up as not released."; + } + + // Then, alternatively cancel and detach (release) buffers. Only detached + // buffers should be returned by getReleasedBuffersExtended + slotsToFences = dequeueAll(); + std::set<int> cancelledSlots; + std::set<int> detachedSlots; + bool cancel; + for (auto& [slot, fence] : slotsToFences) { + if (cancel) { + EXPECT_EQ(OK, mProducer->cancelBuffer(slot, fence)); + cancelledSlots.insert(slot); + } else { + EXPECT_EQ(OK, mProducer->detachBuffer(slot)); + detachedSlots.insert(slot); + } + cancel = !cancel; + } + + EXPECT_EQ(OK, mConsumer->getReleasedBuffersExtended(&releasedSlots)); + for (int slot : detachedSlots) { + EXPECT_TRUE(releasedSlots[slot]) << "Slots that are detached are released."; + } + for (int slot : cancelledSlots) { + EXPECT_FALSE(releasedSlots[slot]) + << "Slots that are still held in the queue are not released."; + } +} +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) } // namespace android 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 f4239cb69e..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; } @@ -803,6 +802,27 @@ INSTANTIATE_TEST_CASE_P(Rgba8888Tests, ::testing::ValuesIn(rgba8888TestSets)); #endif +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +TEST(CpuConsumerSlotTest, UnlimitedSlots_AcquireReleaseAll) { + sp<CpuConsumer> cpuConsumer = sp<CpuConsumer>::make(3); + sp<Surface> surface = cpuConsumer->getSurface(); + sp<SurfaceListener> listener = sp<StubSurfaceListener>::make(); + ASSERT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, listener)); + ASSERT_EQ(OK, surface->setMaxDequeuedBufferCount(256)); + std::vector<Surface::BatchBuffer> buffers(256); + EXPECT_EQ(OK, surface->dequeueBuffers(&buffers)); + + for (auto& buffer : buffers) { + sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(buffer.buffer); + sp<Fence> fence = sp<Fence>::make(buffer.fenceFd); + EXPECT_EQ(OK, surface->queueBuffer(graphicBuffer, fence)); + + CpuConsumer::LockedBuffer nativeBuffer; + EXPECT_EQ(OK, cpuConsumer->lockNextBuffer(&nativeBuffer)); + EXPECT_EQ(OK, cpuConsumer->unlockBuffer(nativeBuffer)); + } +} +#endif } // namespace android 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/FillBuffer.cpp b/libs/gui/tests/FillBuffer.cpp index b60995a624..11383d906b 100644 --- a/libs/gui/tests/FillBuffer.cpp +++ b/libs/gui/tests/FillBuffer.cpp @@ -76,7 +76,7 @@ void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride, } void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) { - const size_t PIXEL_SIZE = 4; + constexpr size_t PIXEL_SIZE = 4; for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { off_t offset = (y * stride + x) * PIXEL_SIZE; @@ -89,6 +89,21 @@ void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) { } } +void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride, uint8_t r, uint8_t g, uint8_t b, + uint8_t a) { + constexpr size_t PIXEL_SIZE = 4; + + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + off_t offset = (y * stride + x) * PIXEL_SIZE; + buf[offset] = r; + buf[offset + 1] = g; + buf[offset + 2] = b; + buf[offset + 3] = a; + } + } +} + void produceOneRGBA8Frame(const sp<ANativeWindow>& anw) { android_native_buffer_t* anb; ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(), diff --git a/libs/gui/tests/FillBuffer.h b/libs/gui/tests/FillBuffer.h index b584179318..f5d6b8bbda 100644 --- a/libs/gui/tests/FillBuffer.h +++ b/libs/gui/tests/FillBuffer.h @@ -30,6 +30,8 @@ void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride, const android_native_rect_t& rect); void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride); +void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride, uint8_t r, uint8_t g, uint8_t b, + uint8_t a); // Produce a single RGBA8 frame by filling a buffer with a checkerboard pattern // using the CPU. This assumes that the ANativeWindow is already configured to diff --git a/libs/gui/tests/FrameRateUtilsTest.cpp b/libs/gui/tests/FrameRateUtilsTest.cpp index 9ffe91f460..c5025331e1 100644 --- a/libs/gui/tests/FrameRateUtilsTest.cpp +++ b/libs/gui/tests/FrameRateUtilsTest.cpp @@ -34,7 +34,7 @@ TEST(FrameRateUtilsTest, ValidateFrameRate) { ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS, "")); EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); - EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE, + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_AT_LEAST, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); // Privileged APIs. 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/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp index 449533aa57..b22b85332c 100644 --- a/libs/gui/tests/SurfaceTextureGL_test.cpp +++ b/libs/gui/tests/SurfaceTextureGL_test.cpp @@ -17,6 +17,8 @@ #define LOG_TAG "SurfaceTextureGL_test" //#define LOG_NDEBUG 0 +#include <gmock/gmock.h> + #include "SurfaceTextureGL.h" #include "DisconnectWaiter.h" @@ -735,4 +737,30 @@ TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) { ASSERT_NE(NO_ERROR, mST->updateTexImage()); } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) +TEST_F(SurfaceTextureGLTest, TestUnlimitedSlots) { + ASSERT_EQ(OK, mSTC->connect(NATIVE_WINDOW_API_CPU, sp<StubSurfaceListener>::make())); + ASSERT_EQ(OK, mSTC->setMaxDequeuedBufferCount(256)); + + std::vector<Surface::BatchBuffer> buffers(256); + ASSERT_EQ(OK, mSTC->dequeueBuffers(&buffers)); + ASSERT_EQ(256u, buffers.size()); + ASSERT_THAT(buffers, Each(Field(&Surface::BatchBuffer::buffer, ::testing::NotNull()))); + + for (size_t i = 0; i < buffers.size(); ++i) { + sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(buffers[i].buffer); + sp<Fence> fence = sp<Fence>::make(buffers[i].fenceFd); + + void* buf; + ASSERT_EQ(OK, graphicBuffer->lock(AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, &buf)); + fillRGBA8Buffer((uint8_t*)buf, graphicBuffer->getWidth(), graphicBuffer->getHeight(), + graphicBuffer->getStride(), i, i, i, i); + graphicBuffer->unlock(); + + ASSERT_EQ(OK, mSTC->queueBuffer(graphicBuffer, fence)); + ASSERT_EQ(OK, mST->updateTexImage()); + checkPixel(0, 0, i, i, i, i); + } +} +#endif } // namespace android diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 76362ff272..eb55e3baeb 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -14,10 +14,6 @@ * limitations under the License. */ -#include "gui/view/Surface.h" -#include "Constants.h" -#include "MockConsumer.h" - #include <gtest/gtest.h> #include <SurfaceFlingerProperties.h> @@ -36,10 +32,13 @@ #include <gui/IConsumerListener.h> #include <gui/IGraphicBufferConsumer.h> #include <gui/IGraphicBufferProducer.h> +#include <gui/IProducerListener.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> #include <gui/SyncScreenCaptureListener.h> +#include <gui/view/Surface.h> +#include <nativebase/nativebase.h> #include <private/gui/ComposerService.h> #include <private/gui/ComposerServiceAIDL.h> #include <sys/types.h> @@ -47,6 +46,7 @@ #include <ui/BufferQueueDefs.h> #include <ui/DisplayMode.h> #include <ui/GraphicBuffer.h> +#include <ui/PixelFormat.h> #include <ui/Rect.h> #include <utils/Errors.h> #include <utils/String8.h> @@ -55,9 +55,12 @@ #include <cstddef> #include <cstdint> #include <future> +#include <iterator> #include <limits> #include <thread> +#include "Constants.h" +#include "MockConsumer.h" #include "testserver/TestServerClient.h" namespace android { @@ -291,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; @@ -306,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; @@ -322,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 @@ -600,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 {} @@ -1016,7 +1014,11 @@ public: return binder::Status::ok(); } - binder::Status setActivePictureListener(const sp<gui::IActivePictureListener>&) { + binder::Status addActivePictureListener(const sp<gui::IActivePictureListener>&) { + return binder::Status::ok(); + } + + binder::Status removeActivePictureListener(const sp<gui::IActivePictureListener>&) { return binder::Status::ok(); } @@ -2173,8 +2175,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(); @@ -2222,8 +2223,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(); @@ -2370,8 +2370,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); @@ -2529,4 +2528,128 @@ TEST_F(SurfaceTest, QueueBufferOutput_TracksReplacements_Plural) { } #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS) +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) +TEST_F(SurfaceTest, UnlimitedSlots_FailsOnIncompatibleConsumer) { + sp<IGraphicBufferProducer> producer; + sp<IGraphicBufferConsumer> consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + + sp<IConsumerListener> consumerListener = sp<FakeConsumer>::make(); + + EXPECT_EQ(OK, consumer->allowUnlimitedSlots(false)); + EXPECT_EQ(OK, consumer->consumerConnect(consumerListener, /* consumerListener */ true)); + + sp<Surface> surface = sp<Surface>::make(producer); + sp<SurfaceListener> surfaceListener = sp<StubSurfaceListener>::make(); + EXPECT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, surfaceListener)); + + EXPECT_NE(OK, surface->setMaxDequeuedBufferCount(128)) + << "We shouldn't be able to set high max buffer counts if the consumer doesn't allow " + "it"; +} + +TEST_F(SurfaceTest, UnlimitedSlots_CanDequeueAndQueueMoreThanOldMaximum) { + sp<IGraphicBufferProducer> producer; + sp<IGraphicBufferConsumer> consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + + sp<IConsumerListener> consumerListener = sp<FakeConsumer>::make(); + + EXPECT_EQ(OK, consumer->allowUnlimitedSlots(true)); + EXPECT_EQ(OK, consumer->consumerConnect(consumerListener, /* consumerListener */ true)); + EXPECT_EQ(OK, consumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888)); + EXPECT_EQ(OK, consumer->setConsumerUsageBits(AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN)); + + sp<Surface> surface = sp<Surface>::make(producer); + sp<SurfaceListener> surfaceListener = sp<StubSurfaceListener>::make(); + EXPECT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, surfaceListener)); + + EXPECT_EQ(OK, surface->setMaxDequeuedBufferCount(128)) + << "If unlimited slots are allowed, we should be able increase the max dequeued buffer " + "count arbitrarily"; + + std::vector<std::tuple<sp<GraphicBuffer>, sp<Fence>, int>> buffers; + for (int i = 0; i < 128; i++) { + sp<GraphicBuffer> buffer; + sp<Fence> fence; + ASSERT_EQ(OK, surface->dequeueBuffer(&buffer, &fence)) << "Unable to dequeue buffer #" << i; + buffers.push_back({buffer, fence, i}); + } + + for (auto& [buffer, fence, idx] : buffers) { + ASSERT_EQ(OK, surface->queueBuffer(buffer, fence)) << "Unable to queue buffer #" << idx; + } +} + +TEST_F(SurfaceTest, UnlimitedSlots_CanDequeueAndDetachMoreThanOldMaximum) { + sp<IGraphicBufferProducer> producer; + sp<IGraphicBufferConsumer> consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + + sp<IConsumerListener> consumerListener = sp<FakeConsumer>::make(); + + EXPECT_EQ(OK, consumer->allowUnlimitedSlots(true)); + EXPECT_EQ(OK, consumer->consumerConnect(consumerListener, /* consumerListener */ true)); + EXPECT_EQ(OK, consumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888)); + EXPECT_EQ(OK, consumer->setConsumerUsageBits(AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN)); + + sp<Surface> surface = sp<Surface>::make(producer); + sp<SurfaceListener> surfaceListener = sp<StubSurfaceListener>::make(); + EXPECT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, surfaceListener)); + + EXPECT_EQ(OK, surface->setMaxDequeuedBufferCount(128)) + << "If unlimited slots are allowed, we should be able increase the max dequeued buffer " + "count arbitrarily"; + + std::vector<std::tuple<sp<GraphicBuffer>, sp<Fence>, int>> buffers; + for (int i = 0; i < 128; i++) { + sp<GraphicBuffer> buffer; + sp<Fence> fence; + ASSERT_EQ(OK, surface->dequeueBuffer(&buffer, &fence)) << "Unable to dequeue buffer #" << i; + buffers.push_back({buffer, fence, i}); + } + + for (auto& [buffer, _, idx] : buffers) { + ASSERT_EQ(OK, surface->detachBuffer(buffer)) << "Unable to detach buffer #" << idx; + } +} + +TEST_F(SurfaceTest, UnlimitedSlots_BatchOperations) { + sp<IGraphicBufferProducer> producer; + sp<IGraphicBufferConsumer> consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + + sp<IConsumerListener> consumerListener = sp<FakeConsumer>::make(); + + EXPECT_EQ(OK, consumer->allowUnlimitedSlots(true)); + EXPECT_EQ(OK, consumer->consumerConnect(consumerListener, /* consumerListener */ true)); + EXPECT_EQ(OK, consumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888)); + EXPECT_EQ(OK, consumer->setConsumerUsageBits(AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN)); + + sp<Surface> surface = sp<Surface>::make(producer); + sp<SurfaceListener> surfaceListener = sp<StubSurfaceListener>::make(); + EXPECT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, surfaceListener)); + + EXPECT_EQ(OK, surface->setMaxDequeuedBufferCount(128)) + << "If unlimited slots are allowed, we should be able increase the max dequeued buffer " + "count arbitrarily"; + + std::vector<Surface::BatchBuffer> buffers(128); + EXPECT_EQ(OK, surface->dequeueBuffers(&buffers)); + EXPECT_EQ(128u, buffers.size()); + + std::vector<Surface::BatchQueuedBuffer> queuedBuffers; + std::transform(buffers.begin(), buffers.end(), std::back_inserter(queuedBuffers), + [](Surface::BatchBuffer& buffer) { + Surface::BatchQueuedBuffer out; + out.buffer = buffer.buffer; + out.fenceFd = buffer.fenceFd; + return out; + }); + + std::vector<SurfaceQueueBufferOutput> outputs; + EXPECT_EQ(OK, surface->queueBuffers(queuedBuffers, &outputs)); + EXPECT_EQ(128u, outputs.size()); +} +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) } // 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/benchmarks/Android.bp b/libs/gui/tests/benchmarks/Android.bp new file mode 100644 index 0000000000..a728bef977 --- /dev/null +++ b/libs/gui/tests/benchmarks/Android.bp @@ -0,0 +1,27 @@ +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_benchmark { + name: "libgui_benchmarks", + srcs: [ + "*.cpp", + ], + defaults: ["libgui-defaults"], + static_libs: [ + "libgmock", + "libgtest", + ], + shared_libs: [ + "libgui", + ], + header_libs: [ + "libsurfaceflinger_mocks_headers", + "surfaceflinger_tests_common_headers", + ], +} diff --git a/libs/gui/tests/benchmarks/Transaction_benchmarks.cpp b/libs/gui/tests/benchmarks/Transaction_benchmarks.cpp new file mode 100644 index 0000000000..0a5189538b --- /dev/null +++ b/libs/gui/tests/benchmarks/Transaction_benchmarks.cpp @@ -0,0 +1,139 @@ +/* + * 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. + */ + +#include <benchmark/benchmark.h> +#include <cstddef> +#include <optional> +#include <vector> +#include "binder/Parcel.h" +#include "gui/SurfaceComposerClient.h" +#include "gui/SurfaceControl.h" +#include "log/log_main.h" + +namespace android { +namespace { +using android::hardware::graphics::common::V1_1::BufferUsage; + +std::vector<sp<SurfaceControl>> createSurfaceControl(const char* name, size_t num) { + sp<SurfaceComposerClient> client = sp<SurfaceComposerClient>::make(); + LOG_FATAL_IF(client->initCheck() != OK, "Could not init SurfaceComposerClient"); + std::vector<sp<SurfaceControl>> surfaceControls; + for (size_t i = 0; i < num; i++) { + surfaceControls.push_back( + client->createSurface(String8(name), 0, 0, PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceBufferState)); + } + return surfaceControls; +} + +void applyTransaction(benchmark::State& state) { + std::vector<sp<SurfaceControl>> surfaceControls = createSurfaceControl(__func__, 5 /* num */); + for (auto _ : state) { + SurfaceComposerClient::Transaction t; + for (auto& sc : surfaceControls) { + t.setCrop(sc, FloatRect{1, 2, 3, 4}); + t.setAutoRefresh(sc, true); + t.hide(sc); + t.setAlpha(sc, 0.5); + t.setCornerRadius(sc, 0.8); + } + Parcel p; + t.writeToParcel(&p); + t.clear(); + benchmark::DoNotOptimize(t); + } +} +BENCHMARK(applyTransaction); + +// Mimic a buffer transaction with callbacks +void applyBufferTransaction(benchmark::State& state) { + std::vector<sp<SurfaceControl>> surfaceControls = createSurfaceControl(__func__, 5 /* num */); + std::vector<sp<GraphicBuffer>> buffers; + for (size_t i = 0; i < surfaceControls.size(); i++) { + int64_t usageFlags = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE; + buffers.emplace_back( + sp<GraphicBuffer>::make(5, 5, PIXEL_FORMAT_RGBA_8888, 1, usageFlags, "test")); + } + + for (auto _ : state) { + SurfaceComposerClient::Transaction t; + int i = 0; + for (auto& sc : surfaceControls) { + std::function<void(const ReleaseCallbackId&, const sp<Fence>& /*releaseFence*/, + std::optional<uint32_t> currentMaxAcquiredBufferCount)> + releaseBufferCallback; + t.setBuffer(sc, buffers[i], std::nullopt, std::nullopt, 5, releaseBufferCallback); + } + Parcel p; + // proxy for applying the transaction + t.writeToParcel(&p); + t.clear(); + benchmark::DoNotOptimize(t); + } +} +BENCHMARK(applyBufferTransaction); + +void mergeTransaction(benchmark::State& state) { + std::vector<sp<SurfaceControl>> surfaceControls = createSurfaceControl(__func__, 5 /* num */); + for (auto _ : state) { + SurfaceComposerClient::Transaction t1; + for (auto& sc : surfaceControls) { + t1.setCrop(sc, FloatRect{1, 2, 3, 4}); + t1.setAutoRefresh(sc, true); + t1.hide(sc); + t1.setAlpha(sc, 0.5); + t1.setCornerRadius(sc, 0.8); + } + + SurfaceComposerClient::Transaction t2; + for (auto& sc : surfaceControls) { + t2.hide(sc); + t2.setAlpha(sc, 0.5); + t2.setCornerRadius(sc, 0.8); + t2.setBackgroundBlurRadius(sc, 5); + } + t1.merge(std::move(t2)); + benchmark::DoNotOptimize(t1); + } +} +BENCHMARK(mergeTransaction); + +void readTransactionFromParcel(benchmark::State& state) { + std::vector<sp<SurfaceControl>> surfaceControls = createSurfaceControl(__func__, 5 /* num */); + SurfaceComposerClient::Transaction t; + for (auto& sc : surfaceControls) { + t.setCrop(sc, FloatRect{1, 2, 3, 4}); + t.setAutoRefresh(sc, true); + t.hide(sc); + t.setAlpha(sc, 0.5); + t.setCornerRadius(sc, 0.8); + } + Parcel p; + t.writeToParcel(&p); + t.clear(); + + for (auto _ : state) { + SurfaceComposerClient::Transaction t2; + t2.readFromParcel(&p); + p.setDataPosition(0); + benchmark::DoNotOptimize(t2); + } +} +BENCHMARK(readTransactionFromParcel); + +} // namespace +} // namespace android diff --git a/libs/gui/tests/benchmarks/main.cpp b/libs/gui/tests/benchmarks/main.cpp new file mode 100644 index 0000000000..685c7c6a26 --- /dev/null +++ b/libs/gui/tests/benchmarks/main.cpp @@ -0,0 +1,18 @@ +/* + * 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. + */ + +#include <benchmark/benchmark.h> +BENCHMARK_MAIN(); 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 0a92a71596..1ed9794105 100644 --- a/libs/input/AccelerationCurve.cpp +++ b/libs/input/AccelerationCurve.cpp @@ -40,6 +40,18 @@ static_assert(kSegments.back().maxPointerSpeedMmPerS == std::numeric_limits<doub constexpr std::array<double, 15> kSensitivityFactors = {1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20}; +// Calculates the base gain for a given pointer sensitivity value. +// +// The base gain is a scaling factor that is applied to the pointer movement. +// Higher sensitivity values result in larger base gains, which in turn result +// 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 [1.0, 3.5]. +double calculateBaseGain(int32_t sensitivity) { + return 1.0 + (sensitivity + 7) * (3.5 - 1.0) / (7 + 7); +} + } // namespace std::vector<AccelerationCurveSegment> createAccelerationCurveForPointerSensitivity( @@ -60,4 +72,13 @@ std::vector<AccelerationCurveSegment> createAccelerationCurveForPointerSensitivi return output; } +std::vector<AccelerationCurveSegment> createFlatAccelerationCurve(int32_t sensitivity) { + LOG_ALWAYS_FATAL_IF(sensitivity < -7 || sensitivity > 7, "Invalid pointer sensitivity value"); + std::vector<AccelerationCurveSegment> output = { + AccelerationCurveSegment{std::numeric_limits<double>::infinity(), + calculateBaseGain(sensitivity), + /* reciprocal = */ 0}}; + return output; +} + } // namespace android
\ No newline at end of file diff --git a/libs/input/Android.bp b/libs/input/Android.bp index 389fb7f6ab..ff26184a33 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,15 +212,15 @@ 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", @@ -223,12 +230,13 @@ cc_library { "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 +270,13 @@ cc_library { shared_libs: [ "android.companion.virtualdevice.flags-aconfig-cc", + "libPlatformProperties", "libaconfig_storage_read_api_cc", "libbase", "libbinder", "libbinder_ndk", "libcutils", "liblog", - "libPlatformProperties", "libtinyxml2", "libutils", "libz", // needed by libkernelconfigs @@ -287,15 +295,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 +318,8 @@ cc_library { target: { android: { required: [ - "motion_predictor_model_prebuilt", "motion_predictor_model_config", + "motion_predictor_model_prebuilt", ], static_libs: [ "libstatslog_libinput", @@ -372,9 +380,9 @@ cc_defaults { cpp_std: "c++20", host_supported: true, shared_libs: [ - "libutils", "libbase", "liblog", + "libutils", ], } 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..f866f9b8f0 --- /dev/null +++ b/libs/input/InputFlags.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 <input/InputFlags.h> + +#include <android-base/logging.h> +#include <com_android_input_flags.h> +#include <cutils/properties.h> + +#include <string> + +namespace android { + +bool InputFlags::connectedDisplaysCursorEnabled() { + 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 6a55726db1..d388d48e8d 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -327,8 +327,8 @@ std::unique_ptr<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd, sp<IBinder> token) { const int result = fcntl(fd, F_SETFL, O_NONBLOCK); if (result != 0) { - LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(), - strerror(errno)); + LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket (%d) non-blocking: %s", name.c_str(), + fd.get(), strerror(errno)); return nullptr; } // using 'new' to access a non-public constructor @@ -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/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index 90d29dd190..d2c49b113d 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -615,7 +615,7 @@ std::unique_ptr<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) ALOGE("%s: Null parcel", __func__); return nullptr; } - std::string loadFileName = parcel->readCString(); + std::string loadFileName = parcel->readString8().c_str(); std::unique_ptr<KeyCharacterMap> map = std::make_unique<KeyCharacterMap>(KeyCharacterMap(loadFileName)); map->mType = static_cast<KeyCharacterMap::KeyboardType>(parcel->readInt32()); @@ -704,7 +704,7 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { ALOGE("%s: Null parcel", __func__); return; } - parcel->writeCString(mLoadFileName.c_str()); + parcel->writeString8(String8(mLoadFileName.c_str())); parcel->writeInt32(static_cast<int32_t>(mType)); parcel->writeBool(mLayoutOverlayApplied); diff --git a/libs/input/android/os/IInputConstants.aidl b/libs/input/android/os/IInputConstants.aidl index 31592cd6e3..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. @@ -76,6 +92,9 @@ interface IInputConstants /* The default pointer acceleration value. */ const int DEFAULT_POINTER_ACCELERATION = 3; + /* The default mouse wheel acceleration value. */ + const int DEFAULT_MOUSE_WHEEL_ACCELERATION = 4; + /** * Use the default Velocity Tracker Strategy. Different axes may use different default * strategies. 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 fd7704815f..9d387fe1ec 100644 --- a/libs/input/input_flags.aconfig +++ b/libs/input/input_flags.aconfig @@ -16,6 +16,16 @@ flag { } flag { + name: "enable_button_state_verification" + namespace: "input" + description: "Set to true to enable crashing whenever bad inbound events are going into InputDispatcher" + bug: "392870542" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "remove_input_channel_from_windowstate" namespace: "input" description: "Do not store a copy of input channel inside WindowState." @@ -37,9 +47,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,13 +61,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" @@ -79,13 +82,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" @@ -109,13 +105,6 @@ flag { } flag { - name: "enable_touchpad_fling_stop" - namespace: "input" - description: "Enable fling scrolling to be stopped by putting a finger on the touchpad again" - bug: "281106755" -} - -flag { name: "enable_prediction_pruning_via_jerk_thresholding" namespace: "input" description: "Enable prediction pruning based on jerk thresholds." @@ -195,6 +184,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." @@ -231,3 +230,40 @@ 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 + } +} 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/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 0167c433cb..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,33 +53,41 @@ cc_test { ], cflags: [ "-Wall", - "-Wextra", "-Werror", + "-Wextra", "-Wno-unused-parameter", ], sanitize: { + address: true, hwaddress: true, undefined: true, all_undefined: true, diag: { + cfi: true, + integer_overflow: true, + memtag_heap: true, undefined: true, + misc_undefined: [ + "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, @@ -92,11 +100,6 @@ cc_test { "libstatssocket_lazy", ], }, - host: { - sanitize: { - address: true, - }, - }, }, native_coverage: false, } @@ -114,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/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp index bed31e27a8..24c2c74532 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, 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/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h index ed3e8c1a62..10abb7c927 100644 --- a/libs/nativewindow/include/android/native_window.h +++ b/libs/nativewindow/include/android/native_window.h @@ -258,11 +258,11 @@ enum ANativeWindow_FrameRateCompatibility { ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1, /** - * The window requests a frame rate that is greater than or equal to the specified frame rate. + * The window requests a frame rate that is at least the specified frame rate. * This value should be used for UIs, animations, scrolling, and anything that is not a game * or video. */ - ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE = 2 + ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_AT_LEAST = 2 }; /** 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 243532bc4d..a22c975588 100644 --- a/libs/permission/include/binder/AppOpsManager.h +++ b/libs/permission/include/binder/AppOpsManager.h @@ -148,7 +148,10 @@ public: OP_BLUETOOTH_ADVERTISE = 114, OP_RECORD_INCOMING_PHONE_AUDIO = 115, OP_NEARBY_WIFI_DEVICES = 116, - _NUM_OP = 117 + // 116 - 154 omitted due to lack of use in native + OP_CONTROL_AUDIO = 154, + OP_CONTROL_AUDIO_PARTIAL = 155, + _NUM_OP = 156, }; enum { @@ -177,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/RenderEngine.cpp b/libs/renderengine/RenderEngine.cpp index 907590a236..873fc67c65 100644 --- a/libs/renderengine/RenderEngine.cpp +++ b/libs/renderengine/RenderEngine.cpp @@ -107,16 +107,15 @@ ftl::Future<FenceResult> RenderEngine::drawLayers(const DisplaySettings& display return resultFuture; } -ftl::Future<FenceResult> RenderEngine::drawGainmap( - const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence, +ftl::Future<FenceResult> RenderEngine::tonemapAndDrawGainmap( const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence, - float hdrSdrRatio, ui::Dataspace dataspace, + float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr, const std::shared_ptr<ExternalTexture>& gainmap) { const auto resultPromise = std::make_shared<std::promise<FenceResult>>(); std::future<FenceResult> resultFuture = resultPromise->get_future(); updateProtectedContext({}, {sdr.get(), hdr.get(), gainmap.get()}); - drawGainmapInternal(std::move(resultPromise), sdr, std::move(sdrFence), hdr, - std::move(hdrFence), hdrSdrRatio, dataspace, gainmap); + tonemapAndDrawGainmapInternal(std::move(resultPromise), hdr, std::move(hdrFence), hdrSdrRatio, + dataspace, sdr, gainmap); return resultFuture; } 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/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h index 95c4d033e2..c2dd4ae97e 100644 --- a/libs/renderengine/include/renderengine/RenderEngine.h +++ b/libs/renderengine/include/renderengine/RenderEngine.h @@ -217,12 +217,17 @@ public: const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence); - virtual ftl::Future<FenceResult> drawGainmap(const std::shared_ptr<ExternalTexture>& sdr, - base::borrowed_fd&& sdrFence, - const std::shared_ptr<ExternalTexture>& hdr, - base::borrowed_fd&& hdrFence, float hdrSdrRatio, - ui::Dataspace dataspace, - const std::shared_ptr<ExternalTexture>& gainmap); + // Tonemaps an HDR input image and draws an SDR rendition, plus a gainmap + // describing how to recover the HDR image. + // + // The HDR input image is ALWAYS encoded with an sRGB transfer function and + // is a floating point format. Accordingly, the hdrSdrRatio describes the + // max luminance in the HDR input image above SDR, and the dataspace + // describes the input primaries. + virtual ftl::Future<FenceResult> tonemapAndDrawGainmap( + const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence, + float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr, + const std::shared_ptr<ExternalTexture>& gainmap); // Clean-up method that should be called on the main thread after the // drawFence returned by drawLayers fires. This method will free up @@ -310,11 +315,10 @@ protected: const DisplaySettings& display, const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) = 0; - virtual void drawGainmapInternal( + virtual void tonemapAndDrawGainmapInternal( const std::shared_ptr<std::promise<FenceResult>>&& resultPromise, - const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence, const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence, - float hdrSdrRatio, ui::Dataspace dataspace, + float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr, const std::shared_ptr<ExternalTexture>& gainmap) = 0; }; diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h index fb8331d870..c42e4034e0 100644 --- a/libs/renderengine/include/renderengine/mock/RenderEngine.h +++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h @@ -46,17 +46,16 @@ public: ftl::Future<FenceResult>(const DisplaySettings&, const std::vector<LayerSettings>&, const std::shared_ptr<ExternalTexture>&, base::unique_fd&&)); - MOCK_METHOD7(drawGainmap, + MOCK_METHOD6(tonemapAndDrawGainmap, ftl::Future<FenceResult>(const std::shared_ptr<ExternalTexture>&, - base::borrowed_fd&&, - const std::shared_ptr<ExternalTexture>&, base::borrowed_fd&&, float, ui::Dataspace, + const std::shared_ptr<ExternalTexture>&, const std::shared_ptr<ExternalTexture>&)); - MOCK_METHOD8(drawGainmapInternal, + MOCK_METHOD7(tonemapAndDrawGainmapInternal, void(const std::shared_ptr<std::promise<FenceResult>>&&, - const std::shared_ptr<ExternalTexture>&, base::borrowed_fd&&, const std::shared_ptr<ExternalTexture>&, base::borrowed_fd&&, float, - ui::Dataspace, const std::shared_ptr<ExternalTexture>&)); + ui::Dataspace, const std::shared_ptr<ExternalTexture>&, + const std::shared_ptr<ExternalTexture>&)); MOCK_METHOD5(drawLayersInternal, void(const std::shared_ptr<std::promise<FenceResult>>&&, const DisplaySettings&, const std::vector<LayerSettings>&, const std::shared_ptr<ExternalTexture>&, diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp index 3b0f03671b..9f64d2c4db 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 { @@ -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,38 @@ 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) { + 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 +827,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 +851,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 b9869672de..5f2d1b1be6 100644 --- a/libs/renderengine/skia/SkiaRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaRenderEngine.cpp @@ -544,9 +544,18 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader( } if (graphicBuffer && parameters.layer.luts) { + const bool dimInLinearSpace = parameters.display.dimmingStage != + aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF; + const ui::Dataspace runtimeEffectDataspace = !dimInLinearSpace + ? static_cast<ui::Dataspace>( + (parameters.outputDataSpace & ui::Dataspace::STANDARD_MASK) | + ui::Dataspace::TRANSFER_GAMMA2_2 | + (parameters.outputDataSpace & ui::Dataspace::RANGE_MASK)) + : parameters.outputDataSpace; + shader = mLutShader.lutShader(shader, parameters.layer.luts, parameters.layer.sourceDataspace, - toSkColorSpace(parameters.outputDataSpace)); + toSkColorSpace(runtimeEffectDataspace)); } if (parameters.requiresLinearEffect) { @@ -567,9 +576,7 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader( if (usingLocalTonemap) { const float inputRatio = hdrType == HdrRenderType::GENERIC_HDR ? 1.0f : parameters.layerDimmingRatio; - static MouriMap kMapper; - shader = kMapper.mouriMap(getActiveContext(), shader, inputRatio, - parameters.display.targetHdrSdrRatio); + shader = localTonemap(shader, inputRatio, parameters.display.targetHdrSdrRatio); } // disable tonemapping if we already locally tonemapped @@ -610,6 +617,12 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader( return shader; } +sk_sp<SkShader> SkiaRenderEngine::localTonemap(sk_sp<SkShader> shader, float inputMultiplier, + float targetHdrSdrRatio) { + static MouriMap kMapper; + return kMapper.mouriMap(getActiveContext(), shader, inputMultiplier, targetHdrSdrRatio); +} + void SkiaRenderEngine::initCanvas(SkCanvas* canvas, const DisplaySettings& display) { if (CC_UNLIKELY(mCapture->isCaptureRunning())) { // Record display settings when capture is running. @@ -825,8 +838,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 @@ -840,12 +852,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); @@ -878,12 +887,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()); @@ -907,6 +910,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, @@ -1212,44 +1238,58 @@ void SkiaRenderEngine::drawLayersInternal( resultPromise->set_value(std::move(drawFence)); } -void SkiaRenderEngine::drawGainmapInternal( +void SkiaRenderEngine::tonemapAndDrawGainmapInternal( const std::shared_ptr<std::promise<FenceResult>>&& resultPromise, - const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence, const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence, - float hdrSdrRatio, ui::Dataspace dataspace, + float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr, const std::shared_ptr<ExternalTexture>& gainmap) { std::lock_guard<std::mutex> lock(mRenderingMutex); auto context = getActiveContext(); - auto surfaceTextureRef = getOrCreateBackendTexture(gainmap->getBuffer(), true); - sk_sp<SkSurface> dstSurface = - surfaceTextureRef->getOrCreateSurface(ui::Dataspace::V0_SRGB_LINEAR); - - waitFence(context, sdrFence); - const auto sdrTextureRef = getOrCreateBackendTexture(sdr->getBuffer(), false); - const auto sdrImage = sdrTextureRef->makeImage(dataspace, kPremul_SkAlphaType); - const auto sdrShader = - sdrImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, - SkSamplingOptions({SkFilterMode::kLinear, SkMipmapMode::kNone}), - nullptr); + auto gainmapTextureRef = getOrCreateBackendTexture(gainmap->getBuffer(), true); + sk_sp<SkSurface> gainmapSurface = + gainmapTextureRef->getOrCreateSurface(ui::Dataspace::V0_SRGB_LINEAR); + + auto sdrTextureRef = getOrCreateBackendTexture(sdr->getBuffer(), true); + sk_sp<SkSurface> sdrSurface = sdrTextureRef->getOrCreateSurface(dataspace); + waitFence(context, hdrFence); const auto hdrTextureRef = getOrCreateBackendTexture(hdr->getBuffer(), false); const auto hdrImage = hdrTextureRef->makeImage(dataspace, kPremul_SkAlphaType); const auto hdrShader = hdrImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, - SkSamplingOptions({SkFilterMode::kLinear, SkMipmapMode::kNone}), + SkSamplingOptions({SkFilterMode::kNearest, SkMipmapMode::kNone}), nullptr); + const auto tonemappedShader = localTonemap(hdrShader, 1.0f, 1.0f); + static GainmapFactory kGainmapFactory; - const auto gainmapShader = kGainmapFactory.createSkShader(sdrShader, hdrShader, hdrSdrRatio); + const auto gainmapShader = + kGainmapFactory.createSkShader(tonemappedShader, hdrShader, hdrSdrRatio); - const auto canvas = dstSurface->getCanvas(); - SkPaint paint; - paint.setShader(gainmapShader); - paint.setBlendMode(SkBlendMode::kSrc); - canvas->drawPaint(paint); + sp<Fence> drawFence; - auto drawFence = sp<Fence>::make(flushAndSubmit(context, dstSurface)); - trace(drawFence); + { + const auto canvas = sdrSurface->getCanvas(); + SkPaint paint; + paint.setShader(tonemappedShader); + paint.setBlendMode(SkBlendMode::kSrc); + canvas->drawPaint(paint); + + drawFence = sp<Fence>::make(flushAndSubmit(context, sdrSurface)); + trace(drawFence); + } + + { + const auto canvas = gainmapSurface->getCanvas(); + SkPaint paint; + paint.setShader(gainmapShader); + paint.setBlendMode(SkBlendMode::kSrc); + canvas->drawPaint(paint); + + auto gmFence = sp<Fence>::make(flushAndSubmit(context, gainmapSurface)); + trace(gmFence); + drawFence = Fence::merge("gm-ss", drawFence, gmFence); + } resultPromise->set_value(std::move(drawFence)); } diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h index 7be4c253e7..92b7af985c 100644 --- a/libs/renderengine/skia/SkiaRenderEngine.h +++ b/libs/renderengine/skia/SkiaRenderEngine.h @@ -143,13 +143,11 @@ private: const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) override final; - void drawGainmapInternal(const std::shared_ptr<std::promise<FenceResult>>&& resultPromise, - const std::shared_ptr<ExternalTexture>& sdr, - base::borrowed_fd&& sdrFence, - const std::shared_ptr<ExternalTexture>& hdr, - base::borrowed_fd&& hdrFence, float hdrSdrRatio, - ui::Dataspace dataspace, - const std::shared_ptr<ExternalTexture>& gainmap) override final; + void tonemapAndDrawGainmapInternal( + const std::shared_ptr<std::promise<FenceResult>>&& resultPromise, + const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence, + float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr, + const std::shared_ptr<ExternalTexture>& gainmap) override final; void dump(std::string& result) override final; @@ -168,6 +166,8 @@ private: }; sk_sp<SkShader> createRuntimeEffectShader(const RuntimeEffectShaderParameters&); + sk_sp<SkShader> localTonemap(sk_sp<SkShader>, float inputMultiplier, float targetHdrSdrRatio); + const PixelFormat mDefaultPixelFormat; // Identifier used for various mappings of layers to various diff --git a/libs/renderengine/skia/VulkanInterface.cpp b/libs/renderengine/skia/VulkanInterface.cpp index 37b69f6590..7331bbc418 100644 --- a/libs/renderengine/skia/VulkanInterface.cpp +++ b/libs/renderengine/skia/VulkanInterface.cpp @@ -204,10 +204,10 @@ static skgpu::VulkanGetProc sGetProc = [](const char* proc_name, BAIL("[%s] null", #expr); \ } -#define VK_CHECK(expr) \ - if ((expr) != VK_SUCCESS) { \ - BAIL("[%s] failed. err = %d", #expr, expr); \ - return; \ +#define VK_CHECK(expr) \ + if (VkResult result = (expr); result != VK_SUCCESS) { \ + BAIL("[%s] failed. err = %d", #expr, result); \ + return; \ } #define VK_GET_PROC(F) \ 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/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/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 da47aae15b..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,46 +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); -} - -static sk_sp<SkSurface> makeSurface(SkiaGpuContext* context, const SkRect& origRect, int scale) { - SkImageInfo scaledInfo = - SkImageInfo::MakeN32Premul(ceil(static_cast<float>(origRect.width()) / scale), - ceil(static_cast<float>(origRect.height()) / scale)); - return context->createRenderTarget(scaledInfo); + 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); @@ -124,11 +148,20 @@ sk_sp<SkImage> KawaseBlurDualFilter::generate(SkiaGpuContext* context, const uin const float filterDepth = std::min(kMaxSurfaces - 1.0f, radius * kInputScale / 2.5f); const int filterPasses = std::min(kMaxSurfaces - 1, static_cast<int>(ceil(filterDepth))); + auto makeSurface = [&](float scale) -> sk_sp<SkSurface> { + 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. sk_sp<SkSurface> surfaces[kMaxSurfaces] = - {filterPasses >= 0 ? makeSurface(context, blurRect, 1 * kInverseInputScale) : nullptr, - filterPasses >= 1 ? makeSurface(context, blurRect, 2 * kInverseInputScale) : nullptr, - filterPasses >= 2 ? makeSurface(context, blurRect, 4 * kInverseInputScale) : nullptr}; + {filterPasses >= 0 ? makeSurface(1 * kInverseInputScale) : nullptr, + filterPasses >= 1 ? makeSurface(2 * kInverseInputScale) : nullptr, + filterPasses >= 2 ? makeSurface(4 * kInverseInputScale) : nullptr}; // These weights for scaling offsets per-pass are handpicked to look good at 1 <= radius <= 250. static const float kWeights[5] = { @@ -161,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 5e9dfbba3e..f262158f2c 100644 --- a/libs/renderengine/skia/filters/LutShader.cpp +++ b/libs/renderengine/skia/filters/LutShader.cpp @@ -39,10 +39,13 @@ static const SkString kShader = SkString(R"( uniform int key; uniform int dimension; uniform vec3 luminanceCoefficients; // for CIE_Y + // for hlg/pq transfer function, we need normalize it to [0.0, 1.0] + // we use `normalizeScalar` to do so + uniform float normalizeScalar; vec4 main(vec2 xy) { float4 rgba = image.eval(xy); - float3 linear = toLinearSrgb(rgba.rgb); + float3 linear = toLinearSrgb(rgba.rgb) * normalizeScalar; if (dimension == 1) { // RGB if (key == 0) { @@ -52,19 +55,19 @@ static const SkString kShader = SkString(R"( float gainR = lut.eval(vec2(indexR, 0.0) + 0.5).r; float gainG = lut.eval(vec2(indexG, 0.0) + 0.5).r; float gainB = lut.eval(vec2(indexB, 0.0) + 0.5).r; - return float4(linear.r * gainR, linear.g * gainG, linear.b * gainB, rgba.a); + linear = float3(linear.r * gainR, linear.g * gainG, linear.b * gainB); // MAX_RGB } else if (key == 1) { float maxRGB = max(linear.r, max(linear.g, linear.b)); float index = maxRGB * float(size - 1); float gain = lut.eval(vec2(index, 0.0) + 0.5).r; - return float4(linear * gain, rgba.a); + linear = linear * gain; // CIE_Y } else if (key == 2) { float y = dot(linear, luminanceCoefficients) / 3.0; float index = y * float(size - 1); float gain = lut.eval(vec2(index, 0.0) + 0.5).r; - return float4(linear * gain, rgba.a); + linear = linear * gain; } } else if (dimension == 3) { if (key == 0) { @@ -110,12 +113,10 @@ static const SkString kShader = SkString(R"( float3 c0 = mix(c00, c10, linear.g); float3 c1 = mix(c01, c11, linear.g); - float3 val = mix(c0, c1, linear.b); - - return float4(val, rgba.a); + linear = mix(c0, c1, linear.b); } } - return rgba; + return float4(linear, rgba.a); })"); // same as shader::toColorSpace function @@ -181,15 +182,21 @@ 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())) { - LOG_ALWAYS_FATAL("unable to install pixels"); + ALOGW("bitmap.installPixels failed, skip this Lut!"); + return input; } sk_sp<SkImage> lutImage = SkImages::RasterFromBitmap(bitmap); + if (!lutImage) { + ALOGW("Got a nullptr from SkImages::RasterFromBitmap, skip this Lut!"); + return input; + } + mBuilder->child("image") = input; mBuilder->child("lut") = lutImage->makeRawShader(SkTileMode::kClamp, SkTileMode::kClamp, @@ -197,9 +204,22 @@ sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input, ? SkSamplingOptions(SkFilterMode::kLinear) : SkSamplingOptions()); + float normalizeScalar = 1.0; + switch (srcDataspace & HAL_DATASPACE_TRANSFER_MASK) { + case HAL_DATASPACE_TRANSFER_HLG: + normalizeScalar = 0.203; + break; + case HAL_DATASPACE_TRANSFER_ST2084: + normalizeScalar = 0.0203; + break; + default: + normalizeScalar = 1.0; + } const int uSize = static_cast<int>(size); const int uKey = static_cast<int>(samplingKey); const int uDimension = static_cast<int>(dimension); + const float uNormalizeScalar = static_cast<float>(normalizeScalar); + if (static_cast<LutProperties::SamplingKey>(samplingKey) == LutProperties::SamplingKey::CIE_Y) { // Use predefined colorspaces of input dataspace so that we can get D65 illuminant mat3 toXYZMatrix(toColorSpace(srcDataspace).getRGBtoXYZ()); @@ -211,6 +231,7 @@ sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input, mBuilder->uniform("size") = uSize; mBuilder->uniform("key") = uKey; mBuilder->uniform("dimension") = uDimension; + mBuilder->uniform("normalizeScalar") = uNormalizeScalar; return mBuilder->makeShader(); } diff --git a/libs/renderengine/skia/filters/MouriMap.cpp b/libs/renderengine/skia/filters/MouriMap.cpp index b099bcf3d7..5dc36e6358 100644 --- a/libs/renderengine/skia/filters/MouriMap.cpp +++ b/libs/renderengine/skia/filters/MouriMap.cpp @@ -30,12 +30,12 @@ sk_sp<SkRuntimeEffect> makeEffect(const SkString& sksl) { } const SkString kCrosstalkAndChunk16x16(R"( uniform shader bitmap; - uniform float hdrSdrRatio; + uniform float inputMultiplier; vec4 main(vec2 xy) { float maximum = 0.0; for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { - float3 linear = toLinearSrgb(bitmap.eval((xy - 0.5) * 16 + 0.5 + vec2(x, y)).rgb) * hdrSdrRatio; + float3 linear = toLinearSrgb(bitmap.eval((xy - 0.5) * 16 + 0.5 + vec2(x, y)).rgb) * inputMultiplier; float maxRGB = max(linear.r, max(linear.g, linear.b)); maximum = max(maximum, log2(max(maxRGB, 1.0))); } @@ -77,12 +77,12 @@ const SkString kTonemap(R"( uniform shader image; uniform shader lux; uniform float scaleFactor; - uniform float hdrSdrRatio; + uniform float inputMultiplier; uniform float targetHdrSdrRatio; vec4 main(vec2 xy) { float localMax = lux.eval(xy * scaleFactor).r; float4 rgba = image.eval(xy); - float3 linear = toLinearSrgb(rgba.rgb) * hdrSdrRatio; + float3 linear = toLinearSrgb(rgba.rgb) * inputMultiplier; if (localMax <= targetHdrSdrRatio) { return float4(fromLinearSrgb(linear), rgba.a); @@ -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 @@ -116,19 +116,19 @@ MouriMap::MouriMap() mTonemap(makeEffect(kTonemap)) {} sk_sp<SkShader> MouriMap::mouriMap(SkiaGpuContext* context, sk_sp<SkShader> input, - float hdrSdrRatio, float targetHdrSdrRatio) { - auto downchunked = downchunk(context, input, hdrSdrRatio); + float inputMultiplier, float targetHdrSdrRatio) { + auto downchunked = downchunk(context, input, inputMultiplier); auto localLux = blur(context, downchunked.get()); - return tonemap(input, localLux.get(), hdrSdrRatio, targetHdrSdrRatio); + return tonemap(input, localLux.get(), inputMultiplier, targetHdrSdrRatio); } sk_sp<SkImage> MouriMap::downchunk(SkiaGpuContext* context, sk_sp<SkShader> input, - float hdrSdrRatio) const { + float inputMultiplier) const { SkMatrix matrix; SkImage* image = input->isAImage(&matrix, (SkTileMode*)nullptr); SkRuntimeShaderBuilder crosstalkAndChunk16x16Builder(mCrosstalkAndChunk16x16); crosstalkAndChunk16x16Builder.child("bitmap") = input; - crosstalkAndChunk16x16Builder.uniform("hdrSdrRatio") = hdrSdrRatio; + crosstalkAndChunk16x16Builder.uniform("inputMultiplier") = inputMultiplier; // TODO: fp16 might be overkill. Most practical surfaces use 8-bit RGB for HDR UI and 10-bit YUV // for HDR video. These downsample operations compute log2(max(linear RGB, 1.0)). So we don't // care about LDR precision since they all resolve to LDR-max. For appropriately mastered HDR @@ -168,7 +168,7 @@ sk_sp<SkImage> MouriMap::blur(SkiaGpuContext* context, SkImage* input) const { LOG_ALWAYS_FATAL_IF(!blurSurface, "%s: Failed to create surface!", __func__); return makeImage(blurSurface.get(), blurBuilder); } -sk_sp<SkShader> MouriMap::tonemap(sk_sp<SkShader> input, SkImage* localLux, float hdrSdrRatio, +sk_sp<SkShader> MouriMap::tonemap(sk_sp<SkShader> input, SkImage* localLux, float inputMultiplier, float targetHdrSdrRatio) const { static constexpr float kScaleFactor = 1.0f / 128.0f; SkRuntimeShaderBuilder tonemapBuilder(mTonemap); @@ -177,7 +177,7 @@ sk_sp<SkShader> MouriMap::tonemap(sk_sp<SkShader> input, SkImage* localLux, floa localLux->makeRawShader(SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone)); tonemapBuilder.uniform("scaleFactor") = kScaleFactor; - tonemapBuilder.uniform("hdrSdrRatio") = hdrSdrRatio; + tonemapBuilder.uniform("inputMultiplier") = inputMultiplier; tonemapBuilder.uniform("targetHdrSdrRatio") = targetHdrSdrRatio; return tonemapBuilder.makeShader(); } diff --git a/libs/renderengine/skia/filters/MouriMap.h b/libs/renderengine/skia/filters/MouriMap.h index 9ba2b6ff9d..f4bfa1549e 100644 --- a/libs/renderengine/skia/filters/MouriMap.h +++ b/libs/renderengine/skia/filters/MouriMap.h @@ -62,10 +62,13 @@ class MouriMap { public: MouriMap(); // Apply the MouriMap tonemmaping operator to the input. - // The HDR/SDR ratio describes the luminace range of the input. 1.0 means SDR. Anything larger - // then 1.0 means that there is headroom above the SDR region. - // Similarly, the target HDR/SDR ratio describes the luminance range of the output. - sk_sp<SkShader> mouriMap(SkiaGpuContext* context, sk_sp<SkShader> input, float inputHdrSdrRatio, + // The inputMultiplier informs how to interpret the luminance encoding of the input. + // For a fixed point input, this is necessary to interpret what "1.0" means for the input + // pixels, so that the luminance can be scaled appropriately, such that the operator can + // transform SDR values to be within 1.0. For a floating point input, "1.0" always means SDR, + // so the caller must pass 1.0. + // The target HDR/SDR ratio describes the luminance range of the output. + sk_sp<SkShader> mouriMap(SkiaGpuContext* context, sk_sp<SkShader> input, float inputMultiplier, float targetHdrSdrRatio); private: diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp index c187f93089..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 { @@ -249,11 +250,10 @@ void RenderEngineThreaded::drawLayersInternal( return; } -void RenderEngineThreaded::drawGainmapInternal( +void RenderEngineThreaded::tonemapAndDrawGainmapInternal( const std::shared_ptr<std::promise<FenceResult>>&& resultPromise, - const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence, const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence, - float hdrSdrRatio, ui::Dataspace dataspace, + float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr, const std::shared_ptr<ExternalTexture>& gainmap) { resultPromise->set_value(Fence::NO_FENCE); return; @@ -281,10 +281,9 @@ ftl::Future<FenceResult> RenderEngineThreaded::drawLayers( return resultFuture; } -ftl::Future<FenceResult> RenderEngineThreaded::drawGainmap( - const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence, +ftl::Future<FenceResult> RenderEngineThreaded::tonemapAndDrawGainmap( const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence, - float hdrSdrRatio, ui::Dataspace dataspace, + float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr, const std::shared_ptr<ExternalTexture>& gainmap) { SFTRACE_CALL(); const auto resultPromise = std::make_shared<std::promise<FenceResult>>(); @@ -292,13 +291,14 @@ ftl::Future<FenceResult> RenderEngineThreaded::drawGainmap( { std::lock_guard lock(mThreadMutex); mNeedsPostRenderCleanup = true; - mFunctionCalls.push([resultPromise, sdr, sdrFence = std::move(sdrFence), hdr, - hdrFence = std::move(hdrFence), hdrSdrRatio, dataspace, + mFunctionCalls.push([resultPromise, hdr, hdrFence = std::move(hdrFence), hdrSdrRatio, + dataspace, sdr, gainmap](renderengine::RenderEngine& instance) mutable { - SFTRACE_NAME("REThreaded::drawGainmap"); - instance.updateProtectedContext({}, {sdr.get(), hdr.get(), gainmap.get()}); - instance.drawGainmapInternal(std::move(resultPromise), sdr, std::move(sdrFence), hdr, - std::move(hdrFence), hdrSdrRatio, dataspace, gainmap); + SFTRACE_NAME("REThreaded::tonemapAndDrawGainmap"); + instance.updateProtectedContext({}, {hdr.get(), sdr.get(), gainmap.get()}); + instance.tonemapAndDrawGainmapInternal(std::move(resultPromise), hdr, + std::move(hdrFence), hdrSdrRatio, dataspace, sdr, + gainmap); }); } mCondition.notify_one(); diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h index cb6e924d81..8554b55030 100644 --- a/libs/renderengine/threaded/RenderEngineThreaded.h +++ b/libs/renderengine/threaded/RenderEngineThreaded.h @@ -55,12 +55,10 @@ public: const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) override; - ftl::Future<FenceResult> drawGainmap(const std::shared_ptr<ExternalTexture>& sdr, - base::borrowed_fd&& sdrFence, - const std::shared_ptr<ExternalTexture>& hdr, - base::borrowed_fd&& hdrFence, float hdrSdrRatio, - ui::Dataspace dataspace, - const std::shared_ptr<ExternalTexture>& gainmap) override; + ftl::Future<FenceResult> tonemapAndDrawGainmap( + const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence, + float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr, + const std::shared_ptr<ExternalTexture>& gainmap) override; int getContextPriority() override; bool supportsBackgroundBlur() override; @@ -77,13 +75,11 @@ protected: const std::vector<LayerSettings>& layers, const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) override; - void drawGainmapInternal(const std::shared_ptr<std::promise<FenceResult>>&& resultPromise, - const std::shared_ptr<ExternalTexture>& sdr, - base::borrowed_fd&& sdrFence, - const std::shared_ptr<ExternalTexture>& hdr, - base::borrowed_fd&& hdrFence, float hdrSdrRatio, - ui::Dataspace dataspace, - const std::shared_ptr<ExternalTexture>& gainmap) override; + void tonemapAndDrawGainmapInternal( + const std::shared_ptr<std::promise<FenceResult>>&& resultPromise, + const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence, + float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr, + const std::shared_ptr<ExternalTexture>& gainmap) override; private: void threadMain(CreateInstanceFactory factory); diff --git a/libs/tracing_perfetto/Android.bp b/libs/tracing_perfetto/Android.bp index 9a2d4f7463..1ef83a4706 100644 --- a/libs/tracing_perfetto/Android.bp +++ b/libs/tracing_perfetto/Android.bp @@ -21,7 +21,7 @@ package { default_applicable_licenses: ["frameworks_native_license"], } -cc_library_shared { +cc_library { name: "libtracing_perfetto", export_include_dirs: [ "include", @@ -37,13 +37,17 @@ cc_library_shared { srcs: [ "tracing_perfetto.cpp", "tracing_perfetto_internal.cpp", + "tracing_sdk.cpp", ], shared_libs: [ "libbase", "libcutils", "libperfetto_c", - "android.os.flags-aconfig-cc-host", + ], + + export_shared_lib_headers: [ + "libperfetto_c", ], host_supported: true, diff --git a/libs/tracing_perfetto/include/tracing_sdk.h b/libs/tracing_perfetto/include/tracing_sdk.h new file mode 100644 index 0000000000..271d7c8563 --- /dev/null +++ b/libs/tracing_perfetto/include/tracing_sdk.h @@ -0,0 +1,451 @@ +/* + * 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. + */ + +#pragma once + +#include <android-base/logging.h> +#include <stdint.h> + +#include <optional> +#include <vector> + +#include "perfetto/public/producer.h" +#include "perfetto/public/te_category_macros.h" +#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 + * underlying native resources. + * + * The static methods prefixed with `delete_` are special. They are designed to be + * invoked by Java through the `NativeAllocationRegistry` when the + * corresponding Java object becomes unreachable. These methods act as + * callbacks to ensure proper deallocation of native resources. + */ +namespace tracing_perfetto { +/** + * @brief Represents extra data associated with a trace event. + * This class manages a collection of PerfettoTeHlExtra pointers. + */ +class Extra; + +/** + * @brief Emits a trace event. + * @param type The type of the event. + * @param cat The category of the event. + * @param name The name of the event. + * @param arg_ptr Pointer to Extra data. + */ +void trace_event(int type, const PerfettoTeCategory* cat, const char* name, + Extra* extra); + +/** + * @brief Gets the process track UUID. + */ +uint64_t get_process_track_uuid(); + +/** + * @brief Gets the thread track UUID for a given PID. + */ +uint64_t get_thread_track_uuid(pid_t tid); + +/** + * @brief Holder for all the other classes in the file. + */ +class Extra { + public: + Extra(); + void push_extra(PerfettoTeHlExtra* extra); + void pop_extra(); + void clear_extras(); + static void delete_extra(Extra* extra); + + PerfettoTeHlExtra* const* get() const; + + private: + DISALLOW_COPY_AND_ASSIGN(Extra); + + // These PerfettoTeHlExtra pointers are really pointers to all the other + // types of extras: Category, DebugArg, Counter etc. Those objects are + // individually managed by Java. + std::vector<PerfettoTeHlExtra*> extras_; +}; + +/** + * @brief Represents a trace event category. + */ +class Category { + public: + Category(const std::string& name, const std::string& tag, + const std::string& severity); + + ~Category(); + + void register_category(); + + void unregister_category(); + + bool is_category_enabled(); + + static void delete_category(Category* category); + + const PerfettoTeCategory* get() const; + + private: + DISALLOW_COPY_AND_ASSIGN(Category); + PerfettoTeCategory category_; + const std::string name_; + const std::string tag_; + const std::string severity_; +}; + +/** + * @brief Represents one end of a flow between two events. + */ +class Flow { + public: + Flow(); + + void set_process_flow(uint64_t id); + void set_process_terminating_flow(uint64_t id); + static void delete_flow(Flow* flow); + + const PerfettoTeHlExtraFlow* get() const; + + private: + DISALLOW_COPY_AND_ASSIGN(Flow); + PerfettoTeHlExtraFlow flow_; +}; + +/** + * @brief Represents a named track. + */ +class NamedTrack { + public: + NamedTrack(uint64_t id, uint64_t parent_uuid, const std::string& name); + + static void delete_track(NamedTrack* track); + + const PerfettoTeHlExtraNamedTrack* get() const; + + private: + DISALLOW_COPY_AND_ASSIGN(NamedTrack); + const std::string name_; + PerfettoTeHlExtraNamedTrack track_; +}; + +/** + * @brief Represents a registered track. + */ +class RegisteredTrack { + public: + RegisteredTrack(uint64_t id, uint64_t parent_uuid, const std::string& name, + bool is_counter); + ~RegisteredTrack(); + + void register_track(); + void unregister_track(); + static void delete_track(RegisteredTrack* track); + + const PerfettoTeHlExtraRegisteredTrack* get() const; + + private: + DISALLOW_COPY_AND_ASSIGN(RegisteredTrack); + PerfettoTeRegisteredTrack registered_track_; + PerfettoTeHlExtraRegisteredTrack track_; + const std::string name_; + const uint64_t id_; + const uint64_t parent_uuid_; + const bool is_counter_; +}; + +/** + * @brief Represents a counter track event. + * @tparam T The data type of the counter (int64_t or double). + */ +template <typename T> +class Counter { + public: + template <typename> + struct always_false : std::false_type {}; + + struct TypeMap { + using type = std::invoke_result_t<decltype([]() { + if constexpr (std::is_same_v<T, int64_t>) { + return std::type_identity<PerfettoTeHlExtraCounterInt64>{}; + } else if constexpr (std::is_same_v<T, double>) { + return std::type_identity<PerfettoTeHlExtraCounterDouble>{}; + } else { + return std::type_identity<void>{}; + } + })>::type; + + static constexpr int enum_value = []() { + if constexpr (std::is_same_v<T, int64_t>) { + return PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_INT64; + } else if constexpr (std::is_same_v<T, double>) { + return PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_DOUBLE; + } else { + static_assert(always_false<T>::value, "Unsupported type"); + return 0; // Never reached, just to satisfy return type + } + }(); + }; + + Counter() { + static_assert(!std::is_same_v<typename TypeMap::type, void>, + "Unsupported type for Counter"); + + typename TypeMap::type counter; + counter.header = {TypeMap::enum_value}; + counter_ = std::move(counter); + } + + void set_value(T value) { + if constexpr (std::is_same_v<T, int64_t>) { + counter_.value = value; + } else if constexpr (std::is_same_v<T, double>) { + counter_.value = value; + } + } + + static void delete_counter(Counter* counter) { + delete counter; + } + + const TypeMap::type* get() const { + return &counter_; + } + + private: + DISALLOW_COPY_AND_ASSIGN(Counter); + TypeMap::type counter_; +}; + +/** + * @brief Represents a debug argument for a trace event. + * @tparam T The data type of the argument (bool, int64_t, double, const char*). + */ +template <typename T> +class DebugArg { + public: + template <typename> + struct always_false : std::false_type {}; + + struct TypeMap { + using type = std::invoke_result_t<decltype([]() { + if constexpr (std::is_same_v<T, bool>) { + return std::type_identity<PerfettoTeHlExtraDebugArgBool>{}; + } else if constexpr (std::is_same_v<T, int64_t>) { + return std::type_identity<PerfettoTeHlExtraDebugArgInt64>{}; + } else if constexpr (std::is_same_v<T, double>) { + return std::type_identity<PerfettoTeHlExtraDebugArgDouble>{}; + } else if constexpr (std::is_same_v<T, const char*>) { + return std::type_identity<PerfettoTeHlExtraDebugArgString>{}; + } else { + return std::type_identity<void>{}; + } + })>::type; + + static constexpr int enum_value = []() { + if constexpr (std::is_same_v<T, bool>) { + return PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_BOOL; + } else if constexpr (std::is_same_v<T, int64_t>) { + return PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_INT64; + } else if constexpr (std::is_same_v<T, double>) { + return PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_DOUBLE; + } else if constexpr (std::is_same_v<T, const char*>) { + return PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_STRING; + } else { + static_assert(always_false<T>::value, "Unsupported type"); + return 0; // Never reached, just to satisfy return type + } + }(); + }; + + DebugArg(const std::string& name) : name_(name) { + static_assert(!std::is_same_v<typename TypeMap::type, void>, + "Unsupported type for DebugArg"); + + typename TypeMap::type arg; + arg.header = {TypeMap::enum_value}; + arg.name = name_.c_str(); + arg_ = std::move(arg); + } + + void set_value(T value) { + if constexpr (std::is_same_v<T, const char*>) { + arg_.value = value; + } else if constexpr (std::is_same_v<T, int64_t>) { + arg_.value = value; + } else if constexpr (std::is_same_v<T, bool>) { + arg_.value = value; + } else if constexpr (std::is_same_v<T, double>) { + arg_.value = value; + } + } + + static void delete_arg(DebugArg* arg) { + delete arg; + } + + const TypeMap::type* get() const { + return &arg_; + } + + private: + DISALLOW_COPY_AND_ASSIGN(DebugArg); + TypeMap::type arg_; + const std::string name_; +}; + +template <typename T> +class ProtoField { + public: + template <typename> + struct always_false : std::false_type {}; + + struct TypeMap { + using type = std::invoke_result_t<decltype([]() { + if constexpr (std::is_same_v<T, int64_t>) { + return std::type_identity<PerfettoTeHlProtoFieldVarInt>{}; + } else if constexpr (std::is_same_v<T, double>) { + return std::type_identity<PerfettoTeHlProtoFieldDouble>{}; + } else if constexpr (std::is_same_v<T, const char*>) { + return std::type_identity<PerfettoTeHlProtoFieldCstr>{}; + } else { + return std::type_identity<void>{}; + } + })>::type; + + static constexpr PerfettoTeHlProtoFieldType enum_value = []() { + if constexpr (std::is_same_v<T, int64_t>) { + return PERFETTO_TE_HL_PROTO_TYPE_VARINT; + } else if constexpr (std::is_same_v<T, double>) { + return PERFETTO_TE_HL_PROTO_TYPE_DOUBLE; + } else if constexpr (std::is_same_v<T, const char*>) { + return PERFETTO_TE_HL_PROTO_TYPE_CSTR; + } else { + static_assert(always_false<T>::value, "Unsupported type"); + return 0; // Never reached, just to satisfy return type + } + }(); + }; + + ProtoField() { + static_assert(!std::is_same_v<typename TypeMap::type, void>, + "Unsupported type for ProtoField"); + + typename TypeMap::type arg; + arg.header.type = TypeMap::enum_value; + arg_ = std::move(arg); + } + + void set_value(uint32_t id, T value) { + if constexpr (std::is_same_v<T, int64_t>) { + arg_.header.id = id; + arg_.value = value; + } else if constexpr (std::is_same_v<T, double>) { + arg_.header.id = id; + arg_.value = value; + } else if constexpr (std::is_same_v<T, const char*>) { + arg_.header.id = id; + arg_.str = value; + } + } + + static void delete_field(ProtoField* field) { + delete field; + } + + const TypeMap::type* get() const { + return &arg_; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ProtoField); + TypeMap::type arg_; +}; + +class ProtoFieldNested { + public: + ProtoFieldNested(); + + void add_field(PerfettoTeHlProtoField* field); + void set_id(uint32_t id); + static void delete_field(ProtoFieldNested* field); + + const PerfettoTeHlProtoFieldNested* get() const; + + private: + DISALLOW_COPY_AND_ASSIGN(ProtoFieldNested); + PerfettoTeHlProtoFieldNested field_; + // These PerfettoTeHlProtoField pointers are really pointers to all the other + // types of protos: PerfettoTeHlProtoFieldVarInt, PerfettoTeHlProtoFieldVarInt, + // PerfettoTeHlProtoFieldVarInt, PerfettoTeHlProtoFieldNested. Those objects are + // individually managed by Java. + std::vector<PerfettoTeHlProtoField*> fields_; +}; + +class Proto { + public: + Proto(); + + void add_field(PerfettoTeHlProtoField* field); + void clear_fields(); + static void delete_proto(Proto* proto); + + const PerfettoTeHlExtraProtoFields* get() const; + + private: + DISALLOW_COPY_AND_ASSIGN(Proto); + PerfettoTeHlExtraProtoFields proto_; + // These PerfettoTeHlProtoField pointers are really pointers to all the other + // types of protos: PerfettoTeHlProtoFieldVarInt, PerfettoTeHlProtoFieldVarInt, + // PerfettoTeHlProtoFieldVarInt, PerfettoTeHlProtoFieldNested. Those objects are + // individually managed by Java. + 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. + * @param ttl_ms The time-to-live of the trigger in milliseconds. + */ +void activate_trigger(const char* name, uint32_t ttl_ms); +} // namespace tracing_perfetto diff --git a/libs/tracing_perfetto/tests/Android.bp b/libs/tracing_perfetto/tests/Android.bp index d203467783..79fb704906 100644 --- a/libs/tracing_perfetto/tests/Android.bp +++ b/libs/tracing_perfetto/tests/Android.bp @@ -36,7 +36,6 @@ cc_test { "android.os.flags-aconfig-cc-host", "libbase", "libperfetto_c", - "liblog", "libprotobuf-cpp-lite", "libtracing_perfetto", ], @@ -44,5 +43,8 @@ cc_test { "tracing_perfetto_test.cpp", "utils.cpp", ], + local_include_dirs: [ + "include", + ], test_suites: ["device-tests"], } diff --git a/libs/tracing_perfetto/tests/include/utils.h b/libs/tracing_perfetto/tests/include/utils.h new file mode 100644 index 0000000000..b2630e1829 --- /dev/null +++ b/libs/tracing_perfetto/tests/include/utils.h @@ -0,0 +1,124 @@ +/* + * 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. + */ + +// Copied from //external/perfetto/src/shared_lib/test/utils.h + +#ifndef UTILS_H +#define UTILS_H + +#include <cassert> +#include <condition_variable> +#include <cstdint> +#include <functional> +#include <iterator> +#include <memory> +#include <mutex> +#include <ostream> +#include <string> +#include <vector> + +#include "perfetto/public/abi/pb_decoder_abi.h" +#include "perfetto/public/pb_utils.h" +#include "perfetto/public/tracing_session.h" + +// Pretty printer for gtest +void PrintTo(const PerfettoPbDecoderField& field, std::ostream*); + +namespace perfetto { +namespace shlib { +namespace test_utils { + +class WaitableEvent { + public: + WaitableEvent() = default; + void Notify() { + std::unique_lock<std::mutex> lock(m_); + notified_ = true; + cv_.notify_one(); + } + bool WaitForNotification() { + std::unique_lock<std::mutex> lock(m_); + cv_.wait(lock, [this] { return notified_; }); + return notified_; + } + bool IsNotified() { + std::unique_lock<std::mutex> lock(m_); + return notified_; + } + + private: + std::mutex m_; + std::condition_variable cv_; + bool notified_ = false; +}; + +class TracingSession { + public: + class Builder { + public: + Builder() = default; + Builder& add_enabled_category(std::string category) { + enabled_categories_.push_back(std::move(category)); + return *this; + } + Builder& add_disabled_category(std::string category) { + disabled_categories_.push_back(std::move(category)); + return *this; + } + Builder& add_atrace_category(std::string category) { + atrace_categories_.push_back(std::move(category)); + return *this; + } + Builder& add_atrace_category_prefer_sdk(std::string category) { + atrace_categories_prefer_sdk_.push_back(std::move(category)); + return *this; + } + TracingSession Build(); + + private: + std::vector<std::string> enabled_categories_; + std::vector<std::string> disabled_categories_; + std::vector<std::string> atrace_categories_; + std::vector<std::string> atrace_categories_prefer_sdk_; + }; + + static TracingSession Adopt(struct PerfettoTracingSessionImpl*); + static TracingSession FromBytes(void *buf, size_t len); + + TracingSession(TracingSession&&) noexcept; + + ~TracingSession(); + + struct PerfettoTracingSessionImpl* session() const { + return session_; + } + + bool FlushBlocking(uint32_t timeout_ms); + void WaitForStopped(); + void StopBlocking(); + std::vector<uint8_t> ReadBlocking(); + + private: + TracingSession() = default; + struct PerfettoTracingSessionImpl* session_; + std::unique_ptr<WaitableEvent> stopped_; +}; + +} // namespace test_utils +} // namespace shlib +} // namespace perfetto + +#endif // UTILS_H diff --git a/libs/tracing_perfetto/tests/tracing_perfetto_test.cpp b/libs/tracing_perfetto/tests/tracing_perfetto_test.cpp index e9fee2e6cf..b21a090677 100644 --- a/libs/tracing_perfetto/tests/tracing_perfetto_test.cpp +++ b/libs/tracing_perfetto/tests/tracing_perfetto_test.cpp @@ -22,6 +22,7 @@ #include <unistd.h> #include "gtest/gtest.h" + #include "perfetto/public/abi/data_source_abi.h" #include "perfetto/public/abi/heap_buffer.h" #include "perfetto/public/abi/pb_decoder_abi.h" diff --git a/libs/tracing_perfetto/tests/utils.cpp b/libs/tracing_perfetto/tests/utils.cpp index 8c4d4a8925..af61bc2192 100644 --- a/libs/tracing_perfetto/tests/utils.cpp +++ b/libs/tracing_perfetto/tests/utils.cpp @@ -34,36 +34,17 @@ namespace perfetto { namespace shlib { namespace test_utils { -namespace { - -std::string ToHexChars(uint8_t val) { - std::string ret; - uint8_t high_nibble = (val & 0xF0) >> 4; - uint8_t low_nibble = (val & 0xF); - static const char hex_chars[] = "0123456789ABCDEF"; - ret.push_back(hex_chars[high_nibble]); - ret.push_back(hex_chars[low_nibble]); - return ret; -} - -} // namespace - TracingSession TracingSession::Builder::Build() { perfetto::protos::TraceConfig trace_config; trace_config.add_buffers()->set_size_kb(1024); - auto* track_event_ds_config = trace_config.add_data_sources()->mutable_config(); - auto* ftrace_ds_config = trace_config.add_data_sources()->mutable_config(); - - track_event_ds_config->set_name("track_event"); - track_event_ds_config->set_target_buffer(0); - - ftrace_ds_config->set_name("linux.ftrace"); - ftrace_ds_config->set_target_buffer(0); - { - auto* ftrace_config = ftrace_ds_config->mutable_ftrace_config(); if (!atrace_categories_.empty()) { + auto* ftrace_ds_config = trace_config.add_data_sources()->mutable_config(); + ftrace_ds_config->set_name("linux.ftrace"); + ftrace_ds_config->set_target_buffer(0); + + auto* ftrace_config = ftrace_ds_config->mutable_ftrace_config(); ftrace_config->add_ftrace_events("ftrace/print"); for (const std::string& cat : atrace_categories_) { ftrace_config->add_atrace_categories(cat); @@ -76,8 +57,14 @@ TracingSession TracingSession::Builder::Build() { } { - auto* track_event_config = track_event_ds_config->mutable_track_event_config(); if (!enabled_categories_.empty() || !disabled_categories_.empty()) { + auto* track_event_ds_config = trace_config.add_data_sources()->mutable_config(); + + track_event_ds_config->set_name("track_event"); + track_event_ds_config->set_target_buffer(0); + + auto* track_event_config = track_event_ds_config->mutable_track_event_config(); + for (const std::string& cat : enabled_categories_) { track_event_config->add_enabled_categories(cat); } @@ -88,13 +75,17 @@ TracingSession TracingSession::Builder::Build() { } } - struct PerfettoTracingSessionImpl* ts = - PerfettoTracingSessionCreate(PERFETTO_BACKEND_SYSTEM); - std::string trace_config_string; trace_config.SerializeToString(&trace_config_string); - PerfettoTracingSessionSetup(ts, trace_config_string.data(), trace_config_string.length()); + return TracingSession::FromBytes(trace_config_string.data(), trace_config_string.length()); +} + +TracingSession TracingSession::FromBytes(void *buf, size_t len) { + struct PerfettoTracingSessionImpl* ts = + PerfettoTracingSessionCreate(PERFETTO_BACKEND_SYSTEM); + + PerfettoTracingSessionSetup(ts, buf, len); // Fails to start here PerfettoTracingSessionStartBlocking(ts); @@ -177,39 +168,3 @@ std::vector<uint8_t> TracingSession::ReadBlocking() { } // namespace test_utils } // namespace shlib } // namespace perfetto - -void PrintTo(const PerfettoPbDecoderField& field, std::ostream* pos) { - std::ostream& os = *pos; - PerfettoPbDecoderStatus status = - static_cast<PerfettoPbDecoderStatus>(field.status); - switch (status) { - case PERFETTO_PB_DECODER_ERROR: - os << "MALFORMED PROTOBUF"; - break; - case PERFETTO_PB_DECODER_DONE: - os << "DECODER DONE"; - break; - case PERFETTO_PB_DECODER_OK: - switch (field.wire_type) { - case PERFETTO_PB_WIRE_TYPE_DELIMITED: - os << "\""; - for (size_t i = 0; i < field.value.delimited.len; i++) { - os << perfetto::shlib::test_utils::ToHexChars( - field.value.delimited.start[i]) - << " "; - } - os << "\""; - break; - case PERFETTO_PB_WIRE_TYPE_VARINT: - os << "varint: " << field.value.integer64; - break; - case PERFETTO_PB_WIRE_TYPE_FIXED32: - os << "fixed32: " << field.value.integer32; - break; - case PERFETTO_PB_WIRE_TYPE_FIXED64: - os << "fixed64: " << field.value.integer64; - break; - } - break; - } -} diff --git a/libs/tracing_perfetto/tests/utils.h b/libs/tracing_perfetto/tests/utils.h deleted file mode 100644 index 8edb4143ee..0000000000 --- a/libs/tracing_perfetto/tests/utils.h +++ /dev/null @@ -1,457 +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. - */ - -// Copied from //external/perfetto/src/shared_lib/test/utils.h - -#ifndef UTILS_H -#define UTILS_H - -#include <cassert> -#include <condition_variable> -#include <cstdint> -#include <functional> -#include <iterator> -#include <memory> -#include <mutex> -#include <ostream> -#include <string> -#include <vector> - -#include "gmock/gmock-matchers.h" -#include "gmock/gmock-more-matchers.h" -#include "gtest/gtest-matchers.h" -#include "gtest/gtest.h" -#include "perfetto/public/abi/pb_decoder_abi.h" -#include "perfetto/public/pb_utils.h" -#include "perfetto/public/tracing_session.h" - -// Pretty printer for gtest -void PrintTo(const PerfettoPbDecoderField& field, std::ostream*); - -namespace perfetto { -namespace shlib { -namespace test_utils { - -class WaitableEvent { - public: - WaitableEvent() = default; - void Notify() { - std::unique_lock<std::mutex> lock(m_); - notified_ = true; - cv_.notify_one(); - } - bool WaitForNotification() { - std::unique_lock<std::mutex> lock(m_); - cv_.wait(lock, [this] { return notified_; }); - return notified_; - } - bool IsNotified() { - std::unique_lock<std::mutex> lock(m_); - return notified_; - } - - private: - std::mutex m_; - std::condition_variable cv_; - bool notified_ = false; -}; - -class TracingSession { - public: - class Builder { - public: - Builder() = default; - Builder& add_enabled_category(std::string category) { - enabled_categories_.push_back(std::move(category)); - return *this; - } - Builder& add_disabled_category(std::string category) { - disabled_categories_.push_back(std::move(category)); - return *this; - } - Builder& add_atrace_category(std::string category) { - atrace_categories_.push_back(std::move(category)); - return *this; - } - Builder& add_atrace_category_prefer_sdk(std::string category) { - atrace_categories_prefer_sdk_.push_back(std::move(category)); - return *this; - } - TracingSession Build(); - - private: - std::vector<std::string> enabled_categories_; - std::vector<std::string> disabled_categories_; - std::vector<std::string> atrace_categories_; - std::vector<std::string> atrace_categories_prefer_sdk_; - }; - - static TracingSession Adopt(struct PerfettoTracingSessionImpl*); - - TracingSession(TracingSession&&) noexcept; - - ~TracingSession(); - - struct PerfettoTracingSessionImpl* session() const { - return session_; - } - - bool FlushBlocking(uint32_t timeout_ms); - void WaitForStopped(); - void StopBlocking(); - std::vector<uint8_t> ReadBlocking(); - - private: - TracingSession() = default; - struct PerfettoTracingSessionImpl* session_; - std::unique_ptr<WaitableEvent> stopped_; -}; - -template <typename FieldSkipper> -class FieldViewBase { - public: - class Iterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = const PerfettoPbDecoderField; - using pointer = value_type; - using reference = value_type; - reference operator*() const { - struct PerfettoPbDecoder decoder; - decoder.read_ptr = read_ptr_; - decoder.end_ptr = end_ptr_; - struct PerfettoPbDecoderField field; - do { - field = PerfettoPbDecoderParseField(&decoder); - } while (field.status == PERFETTO_PB_DECODER_OK && - skipper_.ShouldSkip(field)); - return field; - } - Iterator& operator++() { - struct PerfettoPbDecoder decoder; - decoder.read_ptr = read_ptr_; - decoder.end_ptr = end_ptr_; - PerfettoPbDecoderSkipField(&decoder); - read_ptr_ = decoder.read_ptr; - AdvanceToFirstInterestingField(); - return *this; - } - Iterator operator++(int) { - Iterator tmp = *this; - ++(*this); - return tmp; - } - - friend bool operator==(const Iterator& a, const Iterator& b) { - return a.read_ptr_ == b.read_ptr_; - } - friend bool operator!=(const Iterator& a, const Iterator& b) { - return a.read_ptr_ != b.read_ptr_; - } - - private: - Iterator(const uint8_t* read_ptr, const uint8_t* end_ptr, - const FieldSkipper& skipper) - : read_ptr_(read_ptr), end_ptr_(end_ptr), skipper_(skipper) { - AdvanceToFirstInterestingField(); - } - void AdvanceToFirstInterestingField() { - struct PerfettoPbDecoder decoder; - decoder.read_ptr = read_ptr_; - decoder.end_ptr = end_ptr_; - struct PerfettoPbDecoderField field; - const uint8_t* prev_read_ptr; - do { - prev_read_ptr = decoder.read_ptr; - field = PerfettoPbDecoderParseField(&decoder); - } while (field.status == PERFETTO_PB_DECODER_OK && - skipper_.ShouldSkip(field)); - if (field.status == PERFETTO_PB_DECODER_OK) { - read_ptr_ = prev_read_ptr; - } else { - read_ptr_ = decoder.read_ptr; - } - } - friend class FieldViewBase<FieldSkipper>; - const uint8_t* read_ptr_; - const uint8_t* end_ptr_; - const FieldSkipper& skipper_; - }; - using value_type = const PerfettoPbDecoderField; - using const_iterator = Iterator; - template <typename... Args> - explicit FieldViewBase(const uint8_t* begin, const uint8_t* end, Args... args) - : begin_(begin), end_(end), s_(args...) { - } - template <typename... Args> - explicit FieldViewBase(const std::vector<uint8_t>& data, Args... args) - : FieldViewBase(data.data(), data.data() + data.size(), args...) { - } - template <typename... Args> - explicit FieldViewBase(const struct PerfettoPbDecoderField& field, - Args... args) - : s_(args...) { - if (field.wire_type != PERFETTO_PB_WIRE_TYPE_DELIMITED) { - abort(); - } - begin_ = field.value.delimited.start; - end_ = begin_ + field.value.delimited.len; - } - Iterator begin() const { - return Iterator(begin_, end_, s_); - } - Iterator end() const { - return Iterator(end_, end_, s_); - } - PerfettoPbDecoderField front() const { - return *begin(); - } - - size_t size() const { - size_t count = 0; - for (auto field : *this) { - (void)field; - count++; - } - return count; - } - - bool ok() const { - for (auto field : *this) { - if (field.status != PERFETTO_PB_DECODER_OK) { - return false; - } - } - return true; - } - - private: - const uint8_t* begin_; - const uint8_t* end_; - FieldSkipper s_; -}; - -// Pretty printer for gtest -template <typename FieldSkipper> -void PrintTo(const FieldViewBase<FieldSkipper>& field_view, std::ostream* pos) { - std::ostream& os = *pos; - os << "{"; - for (PerfettoPbDecoderField f : field_view) { - PrintTo(f, pos); - os << ", "; - } - os << "}"; -} - -class IdFieldSkipper { - public: - explicit IdFieldSkipper(uint32_t id) : id_(id) { - } - explicit IdFieldSkipper(int32_t id) : id_(static_cast<uint32_t>(id)) { - } - bool ShouldSkip(const struct PerfettoPbDecoderField& field) const { - return field.id != id_; - } - - private: - uint32_t id_; -}; - -class NoFieldSkipper { - public: - NoFieldSkipper() = default; - bool ShouldSkip(const struct PerfettoPbDecoderField&) const { - return false; - } -}; - -// View over all the fields of a contiguous serialized protobuf message. -// -// Examples: -// -// for (struct PerfettoPbDecoderField field : FieldView(msg_begin, msg_end)) { -// //... -// } -// FieldView fields2(/*PerfettoPbDecoderField*/ nested_field); -// FieldView fields3(/*std::vector<uint8_t>*/ data); -// size_t num = fields1.size(); // The number of fields. -// bool ok = fields1.ok(); // Checks that the message is not malformed. -using FieldView = FieldViewBase<NoFieldSkipper>; - -// Like `FieldView`, but only considers fields with a specific id. -// -// Examples: -// -// IdFieldView fields(msg_begin, msg_end, id) -using IdFieldView = FieldViewBase<IdFieldSkipper>; - -// Matches a PerfettoPbDecoderField with the specified id. Accepts another -// matcher to match the contents of the field. -// -// Example: -// PerfettoPbDecoderField field = ... -// EXPECT_THAT(field, PbField(900, VarIntField(5))); -template <typename M> -auto PbField(int32_t id, M m) { - return testing::AllOf( - testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK), - testing::Field(&PerfettoPbDecoderField::id, id), m); -} - -// Matches a PerfettoPbDecoderField submessage field. Accepts a container -// matcher for the subfields. -// -// Example: -// PerfettoPbDecoderField field = ... -// EXPECT_THAT(field, MsgField(ElementsAre(...))); -template <typename M> -auto MsgField(M m) { - auto f = [](const PerfettoPbDecoderField& field) { return FieldView(field); }; - return testing::AllOf( - testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK), - testing::Field(&PerfettoPbDecoderField::wire_type, - PERFETTO_PB_WIRE_TYPE_DELIMITED), - testing::ResultOf(f, m)); -} - -// Matches a PerfettoPbDecoderField length delimited field. Accepts a string -// matcher. -// -// Example: -// PerfettoPbDecoderField field = ... -// EXPECT_THAT(field, StringField("string")); -template <typename M> -auto StringField(M m) { - auto f = [](const PerfettoPbDecoderField& field) { - return std::string( - reinterpret_cast<const char*>(field.value.delimited.start), - field.value.delimited.len); - }; - return testing::AllOf( - testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK), - testing::Field(&PerfettoPbDecoderField::wire_type, - PERFETTO_PB_WIRE_TYPE_DELIMITED), - testing::ResultOf(f, m)); -} - -// Matches a PerfettoPbDecoderField VarInt field. Accepts an integer matcher -// -// Example: -// PerfettoPbDecoderField field = ... -// EXPECT_THAT(field, VarIntField(1))); -template <typename M> -auto VarIntField(M m) { - auto f = [](const PerfettoPbDecoderField& field) { - return field.value.integer64; - }; - return testing::AllOf( - testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK), - testing::Field(&PerfettoPbDecoderField::wire_type, - PERFETTO_PB_WIRE_TYPE_VARINT), - testing::ResultOf(f, m)); -} - -// Matches a PerfettoPbDecoderField fixed64 field. Accepts an integer matcher -// -// Example: -// PerfettoPbDecoderField field = ... -// EXPECT_THAT(field, Fixed64Field(1))); -template <typename M> -auto Fixed64Field(M m) { - auto f = [](const PerfettoPbDecoderField& field) { - return field.value.integer64; - }; - return testing::AllOf( - testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK), - testing::Field(&PerfettoPbDecoderField::wire_type, - PERFETTO_PB_WIRE_TYPE_FIXED64), - testing::ResultOf(f, m)); -} - -// Matches a PerfettoPbDecoderField fixed32 field. Accepts an integer matcher -// -// Example: -// PerfettoPbDecoderField field = ... -// EXPECT_THAT(field, Fixed32Field(1))); -template <typename M> -auto Fixed32Field(M m) { - auto f = [](const PerfettoPbDecoderField& field) { - return field.value.integer32; - }; - return testing::AllOf( - testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK), - testing::Field(&PerfettoPbDecoderField::wire_type, - PERFETTO_PB_WIRE_TYPE_FIXED32), - testing::ResultOf(f, m)); -} - -// Matches a PerfettoPbDecoderField double field. Accepts a double matcher -// -// Example: -// PerfettoPbDecoderField field = ... -// EXPECT_THAT(field, DoubleField(1.0))); -template <typename M> -auto DoubleField(M m) { - auto f = [](const PerfettoPbDecoderField& field) { - return field.value.double_val; - }; - return testing::AllOf( - testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK), - testing::Field(&PerfettoPbDecoderField::wire_type, - PERFETTO_PB_WIRE_TYPE_FIXED64), - testing::ResultOf(f, m)); -} - -// Matches a PerfettoPbDecoderField float field. Accepts a float matcher -// -// Example: -// PerfettoPbDecoderField field = ... -// EXPECT_THAT(field, FloatField(1.0))); -template <typename M> -auto FloatField(M m) { - auto f = [](const PerfettoPbDecoderField& field) { - return field.value.float_val; - }; - return testing::AllOf( - testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK), - testing::Field(&PerfettoPbDecoderField::wire_type, - PERFETTO_PB_WIRE_TYPE_FIXED32), - testing::ResultOf(f, m)); -} - -// Matches a PerfettoPbDecoderField submessage field. Accepts a container -// matcher for the subfields. -// -// Example: -// PerfettoPbDecoderField field = ... -// EXPECT_THAT(field, AllFieldsWithId(900, ElementsAre(...))); -template <typename M> -auto AllFieldsWithId(int32_t id, M m) { - auto f = [id](const PerfettoPbDecoderField& field) { - return IdFieldView(field, id); - }; - return testing::AllOf( - testing::Field(&PerfettoPbDecoderField::status, PERFETTO_PB_DECODER_OK), - testing::Field(&PerfettoPbDecoderField::wire_type, - PERFETTO_PB_WIRE_TYPE_DELIMITED), - testing::ResultOf(f, m)); -} - -} // namespace test_utils -} // namespace shlib -} // namespace perfetto - -#endif // UTILS_H diff --git a/libs/tracing_perfetto/tracing_perfetto.cpp b/libs/tracing_perfetto/tracing_perfetto.cpp index c35e078b02..4b7021393f 100644 --- a/libs/tracing_perfetto/tracing_perfetto.cpp +++ b/libs/tracing_perfetto/tracing_perfetto.cpp @@ -17,6 +17,7 @@ #include "tracing_perfetto.h" #include <cutils/trace.h> + #include <cstdarg> #include "perfetto/public/te_category_macros.h" @@ -43,8 +44,10 @@ void traceBegin(uint64_t category, const char* name) { void traceFormatBegin(uint64_t category, const char* fmt, ...) { struct PerfettoTeCategory* perfettoTeCategory = internal::toPerfettoCategory(category); - const bool preferAtrace = internal::shouldPreferAtrace(perfettoTeCategory, category); - const bool preferPerfetto = internal::isPerfettoCategoryEnabled(perfettoTeCategory); + const bool preferAtrace = + internal::shouldPreferAtrace(perfettoTeCategory, category); + const bool preferPerfetto = + internal::isPerfettoCategoryEnabled(perfettoTeCategory); if (CC_LIKELY(!(preferAtrace || preferPerfetto))) { return; } @@ -57,7 +60,6 @@ void traceFormatBegin(uint64_t category, const char* fmt, ...) { vsnprintf(buf, BUFFER_SIZE, fmt, ap); va_end(ap); - if (preferAtrace) { atrace_begin(category, buf); } else if (preferPerfetto) { @@ -99,26 +101,28 @@ void traceAsyncEnd(uint64_t category, const char* name, int32_t cookie) { } void traceAsyncBeginForTrack(uint64_t category, const char* name, - const char* trackName, int32_t cookie) { + const char* trackName, int32_t cookie) { struct PerfettoTeCategory* perfettoTeCategory = internal::toPerfettoCategory(category); if (internal::shouldPreferAtrace(perfettoTeCategory, category)) { atrace_async_for_track_begin(category, trackName, name, cookie); } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) { - internal::perfettoTraceAsyncBeginForTrack(*perfettoTeCategory, name, trackName, cookie); + internal::perfettoTraceAsyncBeginForTrack(*perfettoTeCategory, name, + trackName, cookie); } } void traceAsyncEndForTrack(uint64_t category, const char* trackName, - int32_t cookie) { + int32_t cookie) { struct PerfettoTeCategory* perfettoTeCategory = internal::toPerfettoCategory(category); if (internal::shouldPreferAtrace(perfettoTeCategory, category)) { atrace_async_for_track_end(category, trackName, cookie); } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) { - internal::perfettoTraceAsyncEndForTrack(*perfettoTeCategory, trackName, cookie); + internal::perfettoTraceAsyncEndForTrack(*perfettoTeCategory, trackName, + cookie); } } @@ -136,8 +140,10 @@ void traceInstant(uint64_t category, const char* name) { void traceFormatInstant(uint64_t category, const char* fmt, ...) { struct PerfettoTeCategory* perfettoTeCategory = internal::toPerfettoCategory(category); - const bool preferAtrace = internal::shouldPreferAtrace(perfettoTeCategory, category); - const bool preferPerfetto = internal::isPerfettoCategoryEnabled(perfettoTeCategory); + const bool preferAtrace = + internal::shouldPreferAtrace(perfettoTeCategory, category); + const bool preferPerfetto = + internal::isPerfettoCategoryEnabled(perfettoTeCategory); if (CC_LIKELY(!(preferAtrace || preferPerfetto))) { return; } @@ -158,7 +164,7 @@ void traceFormatInstant(uint64_t category, const char* fmt, ...) { } void traceInstantForTrack(uint64_t category, const char* trackName, - const char* name) { + const char* name) { struct PerfettoTeCategory* perfettoTeCategory = internal::toPerfettoCategory(category); @@ -181,20 +187,21 @@ void traceCounter(uint64_t category, const char* name, int64_t value) { } void traceCounter32(uint64_t category, const char* name, int32_t value) { - struct PerfettoTeCategory* perfettoTeCategory = internal::toPerfettoCategory(category); + struct PerfettoTeCategory* perfettoTeCategory = + internal::toPerfettoCategory(category); if (internal::shouldPreferAtrace(perfettoTeCategory, category)) { atrace_int(category, name, value); } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) { internal::perfettoTraceCounter(*perfettoTeCategory, name, - static_cast<int64_t>(value)); + static_cast<int64_t>(value)); } } bool isTagEnabled(uint64_t category) { struct PerfettoTeCategory* perfettoTeCategory = internal::toPerfettoCategory(category); - return internal::isPerfettoCategoryEnabled(perfettoTeCategory) - || atrace_is_tag_enabled(category); + return internal::isPerfettoCategoryEnabled(perfettoTeCategory) || + atrace_is_tag_enabled(category); } } // namespace tracing_perfetto diff --git a/libs/tracing_perfetto/tracing_perfetto_internal.cpp b/libs/tracing_perfetto/tracing_perfetto_internal.cpp index a58bc77131..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") \ @@ -47,7 +48,6 @@ #include <atomic> #include <mutex> -#include <android_os.h> #include <android-base/properties.h> #include <cutils/trace.h> #include <inttypes.h> @@ -228,10 +228,6 @@ struct PerfettoTeCategory* toPerfettoCategory(uint64_t category) { } void registerWithPerfetto(bool test) { - if (!android::os::perfetto_sdk_tracing()) { - return; - } - static std::once_flag registration; std::call_once(registration, [test]() { struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT(); 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 new file mode 100644 index 0000000000..70b8be981b --- /dev/null +++ b/libs/tracing_perfetto/tracing_sdk.cpp @@ -0,0 +1,302 @@ +/* + * 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. + */ + +#include "tracing_sdk.h" + +#include <android-base/logging.h> +#include <cutils/trace.h> + +#include <cstdarg> +#include <cstdlib> + +#include "perfetto/public/abi/producer_abi.h" +#include "perfetto/public/te_category_macros.h" +#include "perfetto/public/te_macros.h" +#include "perfetto/public/track_event.h" +#include "tracing_perfetto.h" + +namespace tracing_perfetto { +void trace_event(int type, const PerfettoTeCategory* perfettoTeCategory, + const char* name, tracing_perfetto::Extra* extra) { + bool enabled = PERFETTO_UNLIKELY(PERFETTO_ATOMIC_LOAD_EXPLICIT( + perfettoTeCategory->enabled, PERFETTO_MEMORY_ORDER_RELAXED)); + if (enabled) { + extra->push_extra(nullptr); + PerfettoTeHlEmitImpl(perfettoTeCategory->impl, type, + type == PERFETTO_TE_TYPE_COUNTER ? nullptr : name, + extra->get()); + extra->clear_extras(); + } +} + +uint64_t get_process_track_uuid() { + return PerfettoTeProcessTrackUuid(); +} + +uint64_t get_thread_track_uuid(pid_t tid) { + // Cating a signed pid_t to unsigned + return PerfettoTeProcessTrackUuid() ^ PERFETTO_STATIC_CAST(uint64_t, tid); +} + +Extra::Extra() { +} + +void Extra::push_extra(PerfettoTeHlExtra* ptr) { + extras_.push_back(ptr); +} + +void Extra::pop_extra() { + extras_.pop_back(); +} + +void Extra::clear_extras() { + extras_.clear(); +} + +void Extra::delete_extra(Extra* ptr) { + delete ptr; +} + +PerfettoTeHlExtra* const* Extra::get() const { + return extras_.data(); +} + +Category::Category(const std::string& name, const std::string& tag, + const std::string& severity) + : category_({.enabled = &perfetto_atomic_false}), + name_(name), + tag_(tag), + severity_(severity) { +} + +Category::~Category() { + unregister_category(); +} + +void Category::register_category() { + if (category_.impl) return; + + std::vector<const char*> tags; + if (!tag_.empty()) tags.push_back(tag_.data()); + if (!severity_.empty()) tags.push_back(severity_.data()); + + category_.desc = {name_.c_str(), name_.c_str(), tags.data(), tags.size()}; + + PerfettoTeCategoryRegister(&category_); + PerfettoTePublishCategories(); +} + +void Category::unregister_category() { + if (!category_.impl) return; + + PerfettoTeCategoryUnregister(&category_); + PerfettoTePublishCategories(); +} + +bool Category::is_category_enabled() { + return PERFETTO_UNLIKELY(PERFETTO_ATOMIC_LOAD_EXPLICIT( + (category_).enabled, PERFETTO_MEMORY_ORDER_RELAXED)); +} + +const PerfettoTeCategory* Category::get() const { + return &category_; +} + +void Category::delete_category(Category* ptr) { + delete ptr; +} + +Flow::Flow() : flow_{} { +} + +void Flow::set_process_flow(uint64_t id) { + flow_.header.type = PERFETTO_TE_HL_EXTRA_TYPE_FLOW; + PerfettoTeFlow ret = PerfettoTeProcessScopedFlow(id); + flow_.id = ret.id; +} + +void Flow::set_process_terminating_flow(uint64_t id) { + flow_.header.type = PERFETTO_TE_HL_EXTRA_TYPE_TERMINATING_FLOW; + PerfettoTeFlow ret = PerfettoTeProcessScopedFlow(id); + flow_.id = ret.id; +} + +const PerfettoTeHlExtraFlow* Flow::get() const { + return &flow_; +} + +void Flow::delete_flow(Flow* ptr) { + delete ptr; +} + +NamedTrack::NamedTrack(uint64_t id, uint64_t parent_uuid, + const std::string& name) + : name_(name), + track_{{PERFETTO_TE_HL_EXTRA_TYPE_NAMED_TRACK}, + name_.data(), + id, + parent_uuid} { +} + +const PerfettoTeHlExtraNamedTrack* NamedTrack::get() const { + return &track_; +} + +void NamedTrack::delete_track(NamedTrack* ptr) { + delete ptr; +} + +RegisteredTrack::RegisteredTrack(uint64_t id, uint64_t parent_uuid, + const std::string& name, bool is_counter) + : registered_track_{}, + track_{{PERFETTO_TE_HL_EXTRA_TYPE_REGISTERED_TRACK}, + &(registered_track_.impl)}, + name_(name), + id_(id), + parent_uuid_(parent_uuid), + is_counter_(is_counter) { + register_track(); +} + +RegisteredTrack::~RegisteredTrack() { + unregister_track(); +} + +void RegisteredTrack::register_track() { + if (registered_track_.impl.descriptor) return; + + if (is_counter_) { + PerfettoTeCounterTrackRegister(®istered_track_, name_.data(), + parent_uuid_); + } else { + PerfettoTeNamedTrackRegister(®istered_track_, name_.data(), id_, + parent_uuid_); + } +} + +void RegisteredTrack::unregister_track() { + if (!registered_track_.impl.descriptor) return; + PerfettoTeRegisteredTrackUnregister(®istered_track_); +} + +const PerfettoTeHlExtraRegisteredTrack* RegisteredTrack::get() const { + return &track_; +} + +void RegisteredTrack::delete_track(RegisteredTrack* ptr) { + delete ptr; +} + +Proto::Proto() : proto_({PERFETTO_TE_HL_EXTRA_TYPE_PROTO_FIELDS}, nullptr) { +} + +void Proto::add_field(PerfettoTeHlProtoField* ptr) { + if (!fields_.empty()) { + fields_.pop_back(); + } + + fields_.push_back(ptr); + fields_.push_back(nullptr); + proto_.fields = fields_.data(); +} + +void Proto::clear_fields() { + fields_.clear(); + proto_.fields = nullptr; +} + +void Proto::delete_proto(Proto* ptr) { + delete ptr; +} + +const PerfettoTeHlExtraProtoFields* Proto::get() const { + return &proto_; +} + +ProtoFieldNested::ProtoFieldNested() + : field_({PERFETTO_TE_HL_PROTO_TYPE_NESTED}, nullptr) { +} + +void ProtoFieldNested::add_field(PerfettoTeHlProtoField* ptr) { + if (!fields_.empty()) { + fields_.pop_back(); + } + + fields_.push_back(ptr); + fields_.push_back(nullptr); + field_.fields = fields_.data(); +} + +void ProtoFieldNested::set_id(uint32_t id) { + fields_.clear(); + field_.header.id = id; + field_.fields = nullptr; +} + +void ProtoFieldNested::delete_field(ProtoFieldNested* ptr) { + delete ptr; +} + +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); +} +} // namespace tracing_perfetto diff --git a/libs/ui/DisplayIdentification.cpp b/libs/ui/DisplayIdentification.cpp index 8d6f74b605..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()) { @@ -417,6 +414,7 @@ std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData( return DisplayIdentificationInfo{ .id = displayId, .name = std::string(edid->displayName), + .port = port, .deviceProductInfo = buildDeviceProductInfo(*edid), .preferredDetailedTimingDescriptor = edid->preferredDetailedTimingDescriptor, }; @@ -426,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/include/ui/DisplayId.h b/libs/ui/include/ui/DisplayId.h index 8a14db8ffa..937e3f1486 100644 --- a/libs/ui/include/ui/DisplayId.h +++ b/libs/ui/include/ui/DisplayId.h @@ -20,7 +20,6 @@ #include <ostream> #include <string> -#include <ftl/hash.h> #include <ftl/optional.h> namespace android { @@ -31,31 +30,16 @@ 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; + static constexpr DisplayId fromValue(uint64_t value) { return DisplayId(value); } constexpr bool isVirtual() const { return value & FLAG_VIRTUAL; } - constexpr bool isStable() const { return value & FLAG_STABLE; } 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,6 +63,9 @@ 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 { + // TODO: b/162612135 - Remove default constructor. + PhysicalDisplayId() = default; + static constexpr ftl::Optional<PhysicalDisplayId> tryCast(DisplayId id) { if (id.isVirtual()) { return std::nullopt; @@ -86,7 +73,7 @@ struct PhysicalDisplayId : DisplayId { return PhysicalDisplayId(id); } - // 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 +86,18 @@ struct PhysicalDisplayId : DisplayId { return PhysicalDisplayId(0, port, kManufacturerId, kModelHash); } - // TODO(b/162612135) Remove default constructor - PhysicalDisplayId() = default; + static constexpr PhysicalDisplayId fromValue(uint64_t value) { + return PhysicalDisplayId(value); + } - constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); } constexpr uint8_t getPort() const { return static_cast<uint8_t>(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) | @@ -127,8 +119,15 @@ struct VirtualDisplayId : DisplayId { 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) {} }; @@ -142,20 +141,17 @@ struct HalVirtualDisplayId : VirtualDisplayId { 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); @@ -163,12 +159,12 @@ struct GpuVirtualDisplayId : VirtualDisplayId { return std::nullopt; } -private: - struct HashTag {}; // Disambiguate with BaseId constructor. - constexpr GpuVirtualDisplayId(HashTag, uint64_t hash) - : VirtualDisplayId(FLAG_STABLE | FLAG_GPU | hash) {} + static constexpr GpuVirtualDisplayId fromValue(uint64_t value) { + return GpuVirtualDisplayId(SkipVirtualFlag{}, value); + } - explicit constexpr GpuVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {} +private: + using VirtualDisplayId::VirtualDisplayId; }; // HalDisplayId is the ID of a display which is managed by HWC. @@ -184,20 +180,13 @@ struct HalDisplayId : DisplayId { 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 {}; -} - static_assert(sizeof(DisplayId) == sizeof(uint64_t)); static_assert(sizeof(HalDisplayId) == sizeof(uint64_t)); static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t)); diff --git a/libs/ui/include/ui/DisplayIdentification.h b/libs/ui/include/ui/DisplayIdentification.h index cf67d7bf93..1e3449c004 100644 --- a/libs/ui/include/ui/DisplayIdentification.h +++ b/libs/ui/include/ui/DisplayIdentification.h @@ -42,6 +42,7 @@ struct DetailedTimingDescriptor { struct DisplayIdentificationInfo { PhysicalDisplayId id; std::string name; + uint8_t port; std::optional<DeviceProductInfo> deviceProductInfo; std::optional<DetailedTimingDescriptor> preferredDetailedTimingDescriptor; }; @@ -73,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; @@ -84,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/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/DisplayId_test.cpp b/libs/ui/tests/DisplayId_test.cpp index ef686dfc83..209acba672 100644 --- a/libs/ui/tests/DisplayId_test.cpp +++ b/libs/ui/tests/DisplayId_test.cpp @@ -26,7 +26,6 @@ TEST(DisplayIdTest, createPhysicalIdFromEdid) { 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)); @@ -34,7 +33,7 @@ TEST(DisplayIdTest, createPhysicalIdFromEdid) { EXPECT_TRUE(HalDisplayId::tryCast(id)); EXPECT_EQ(id, DisplayId::fromValue(id.value)); - EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value)); + EXPECT_EQ(id, PhysicalDisplayId::fromValue(id.value)); } TEST(DisplayIdTest, createPhysicalIdFromPort) { @@ -48,7 +47,7 @@ TEST(DisplayIdTest, createPhysicalIdFromPort) { EXPECT_TRUE(HalDisplayId::tryCast(id)); EXPECT_EQ(id, DisplayId::fromValue(id.value)); - EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value)); + EXPECT_EQ(id, PhysicalDisplayId::fromValue(id.value)); } TEST(DisplayIdTest, createGpuVirtualId) { @@ -60,7 +59,7 @@ TEST(DisplayIdTest, createGpuVirtualId) { EXPECT_FALSE(HalDisplayId::tryCast(id)); EXPECT_EQ(id, DisplayId::fromValue(id.value)); - EXPECT_EQ(id, DisplayId::fromValue<GpuVirtualDisplayId>(id.value)); + EXPECT_EQ(id, GpuVirtualDisplayId::fromValue(id.value)); } TEST(DisplayIdTest, createVirtualIdFromGpuVirtualId) { @@ -75,21 +74,6 @@ TEST(DisplayIdTest, createVirtualIdFromGpuVirtualId) { 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)); @@ -99,7 +83,7 @@ TEST(DisplayIdTest, createHalVirtualId) { EXPECT_TRUE(HalDisplayId::tryCast(id)); EXPECT_EQ(id, DisplayId::fromValue(id.value)); - EXPECT_EQ(id, DisplayId::fromValue<HalVirtualDisplayId>(id.value)); + EXPECT_EQ(id, HalVirtualDisplayId::fromValue(id.value)); } TEST(DisplayIdTest, createVirtualIdFromHalVirtualId) { 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/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/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp index b1a287fcec..0dd9f198e5 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::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/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/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..25ee21fb12 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::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::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::feature_overrides()) { + fprintf(outs, + " featureOverrides update and output gpuservice's feature overrides\n"); + } fclose(outs); return NO_ERROR; } diff --git a/services/gpuservice/feature_override/Android.bp b/services/gpuservice/feature_override/Android.bp new file mode 100644 index 0000000000..3b5407bdd3 --- /dev/null +++ b/services/gpuservice/feature_override/Android.bp @@ -0,0 +1,96 @@ +// 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", + ], + srcs: [ + ":feature_config_proto_definitions", + "FeatureOverrideParser.cpp", + ], + local_include_dirs: [ + "include", + ], + cflags: [ + "-Wall", + "-Werror", + "-Wimplicit-fallthrough", + ], + cppflags: [ + "-Wno-sign-compare", + ], + 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..a16bfa8b35 --- /dev/null +++ b/services/gpuservice/feature_override/FeatureOverrideParser.cpp @@ -0,0 +1,143 @@ +/* + * 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 <graphicsenv/FeatureOverrides.h> +#include <log/log.h> + +#include "feature_config.pb.h" + +namespace { + +void resetFeatureOverrides(android::FeatureOverrides &featureOverrides) { + featureOverrides.mGlobalFeatures.clear(); + featureOverrides.mPackageFeatures.clear(); +} + +void initFeatureConfig(android::FeatureConfig &featureConfig, + const feature_override::FeatureConfig &featureConfigProto) { + featureConfig.mFeatureName = featureConfigProto.feature_name(); + featureConfig.mEnabled = featureConfigProto.enabled(); +} + +feature_override::FeatureOverrideProtos readFeatureConfigProtos(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(); + struct stat fileStat{}; + if (stat(getFeatureOverrideFilePath().c_str(), &fileStat) != 0) { + ALOGE("Error getting file information for '%s': %s", getFeatureOverrideFilePath().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); + + // Global feature overrides. + for (const auto &featureConfigProto: overridesProtos.global_features()) { + FeatureConfig featureConfig; + initFeatureConfig(featureConfig, featureConfigProto); + + 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); + + 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..4d4bf289f1 --- /dev/null +++ b/services/gpuservice/feature_override/proto/feature_config.proto @@ -0,0 +1,53 @@ +/* + * 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; + +/** + * Feature Configuration + * feature_name: Feature name (see external/angle/include/platform/autogen/FeaturesVk_autogen.h). + * enabled: Either enable or disable the feature. + */ +message FeatureConfig +{ + string feature_name = 1; + bool enabled = 2; +} + +/** + * 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..65a1b58dc3 --- /dev/null +++ b/services/gpuservice/tests/unittests/FeatureOverrideParserTest.cpp @@ -0,0 +1,218 @@ +/* + * 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 = 1; + if (overrides.mGlobalFeatures.size() != expectedGlobalFeaturesSize) { + return testing::AssertionFailure() + << "overrides.mGlobalFeatures.size(): " << overrides.mGlobalFeatures.size() + << ", expected: " << expectedGlobalFeaturesSize; + } + + size_t expectedPackageFeaturesSize = 1; + 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 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]; + + 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(); +} + +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..726779e332 --- /dev/null +++ b/services/gpuservice/tests/unittests/data/feature_config_test.txtpb @@ -0,0 +1,40 @@ +# 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 + } +] + +# 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 + } + ] + } +] 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/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java b/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java index 5c12323633..fc0aef4964 100644 --- a/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java +++ b/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java @@ -39,29 +39,9 @@ import java.util.stream.Collectors; @RunWith(DeviceJUnit4ClassRunner.class) public class GpuWorkTracepointTest extends BaseHostJUnit4Test { - private static final String CPU_FREQUENCY_TRACEPOINT_FORMAT_PATH = - "/sys/kernel/tracing/events/power/cpu_frequency/format"; private static final String GPU_WORK_PERIOD_TRACEPOINT_FORMAT_PATH = "/sys/kernel/tracing/events/power/gpu_work_period/format"; - @Test - public void testReadTracingEvents() throws Exception { - // Test |testGpuWorkPeriodTracepointFormat| is dependent on whether certain tracepoint - // paths exist. This means the test will vacuously pass if the tracepoint file system is - // inaccessible. Thus, as a basic check, we make sure the CPU frequency tracepoint format - // is accessible. If not, something is probably fundamentally broken about the tracing - // file system. - CommandResult commandResult = getDevice().executeShellV2Command( - String.format("cat %s", CPU_FREQUENCY_TRACEPOINT_FORMAT_PATH)); - - assertEquals(String.format( - "Failed to read \"%s\". This probably means that the tracing file system " - + "is fundamentally broken in some way, possibly due to bad " - + "permissions.", - CPU_FREQUENCY_TRACEPOINT_FORMAT_PATH), - commandResult.getStatus(), CommandStatus.SUCCESS); - } - @VsrTest(requirements={"VSR-3.3-004"}) @RequiresDevice @Test 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 811692f1bf..98b514ba73 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> @@ -33,37 +36,6 @@ 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) { @@ -98,6 +70,33 @@ std::unordered_set<ui::LogicalDisplayId> getPrivacySensitiveDisplaysFromWindowIn return privacySensitiveDisplays; } +vec2 calculatePositionOnDestinationViewport(const DisplayViewport& destinationViewport, + float pointerOffset, + DisplayTopologyPosition sourceBoundary) { + // destination is opposite of the source boundary + switch (sourceBoundary) { + case DisplayTopologyPosition::RIGHT: + return {0, pointerOffset}; // left edge + case DisplayTopologyPosition::TOP: + return {pointerOffset, destinationViewport.logicalBottom}; // bottom edge + case DisplayTopologyPosition::LEFT: + return {destinationViewport.logicalRight, pointerOffset}; // right edge + case DisplayTopologyPosition::BOTTOM: + return {pointerOffset, 0}; // top edge + } +} + +// 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 --- @@ -133,10 +132,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)), @@ -208,15 +208,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); @@ -294,9 +295,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 @@ -327,19 +330,19 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac // except sometimes near the corners. // In these cases this behaviour is not noticeable. We also do not apply unconsumed delta on // the destination display for the same reason. - DisplayPosition sourceBoundary; + DisplayTopologyPosition sourceBoundary; float cursorOffset = 0.0f; if (rotatedUnconsumedDelta.x > 0) { - sourceBoundary = DisplayPosition::RIGHT; + sourceBoundary = DisplayTopologyPosition::RIGHT; cursorOffset = rotatedCursorPosition.y; } else if (rotatedUnconsumedDelta.x < 0) { - sourceBoundary = DisplayPosition::LEFT; + sourceBoundary = DisplayTopologyPosition::LEFT; cursorOffset = rotatedCursorPosition.y; } else if (rotatedUnconsumedDelta.y > 0) { - sourceBoundary = DisplayPosition::BOTTOM; + sourceBoundary = DisplayTopologyPosition::BOTTOM; cursorOffset = rotatedCursorPosition.x; } else { - sourceBoundary = DisplayPosition::TOP; + sourceBoundary = DisplayTopologyPosition::TOP; cursorOffset = rotatedCursorPosition.x; } @@ -358,7 +361,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)); @@ -369,8 +372,8 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac pc.fade(PointerControllerInterface::Transition::IMMEDIATE); pc.setDisplayViewport(destinationViewport); vec2 destinationPosition = - calculateDestinationPosition(destinationViewport, cursorOffset - destinationOffset, - sourceBoundary); + calculatePositionOnDestinationViewport(destinationViewport, destinationOffset, + sourceBoundary); // Transform position back to un-rotated coordinate space before sending it to controller destinationPosition = pc.getDisplayTransform().inverse().transform(destinationPosition.x, @@ -379,22 +382,6 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac pc.unfade(PointerControllerInterface::Transition::IMMEDIATE); } -vec2 PointerChoreographer::calculateDestinationPosition(const DisplayViewport& destinationViewport, - float pointerOffset, - DisplayPosition sourceBoundary) { - // destination is opposite of the source boundary - switch (sourceBoundary) { - case DisplayPosition::RIGHT: - return {0, pointerOffset}; // left edge - case DisplayPosition::TOP: - return {pointerOffset, destinationViewport.logicalBottom}; // bottom edge - case DisplayPosition::LEFT: - return {destinationViewport.logicalRight, pointerOffset}; // right edge - case DisplayPosition::BOTTOM: - return {pointerOffset, 0}; // top edge - } -} - void PointerChoreographer::processDrawingTabletEventLocked(const android::NotifyMotionArgs& args) { if (args.displayId == ui::LogicalDisplayId::INVALID) { return; @@ -489,6 +476,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, @@ -540,8 +535,7 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args) } void PointerChoreographer::onControllerAddedOrRemovedLocked() { - if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows() && - !com::android::input::flags::connected_displays_cursor()) { + if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows()) { return; } bool requireListener = !mTouchPointersByDevice.empty() || !mMousePointersByDisplay.empty() || @@ -607,11 +601,22 @@ void PointerChoreographer::notifyPointerCaptureChanged( mNextListener.notify(args); } -void PointerChoreographer::setDisplayTopology( - const std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>>& - displayTopology) { - std::scoped_lock _l(getLock()); - mTopology = displayTopology; +void PointerChoreographer::setDisplayTopology(const DisplayTopologyGraph& 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 + + notifyPointerDisplayChange(pointerDisplayChange, mPolicy); } void PointerChoreographer::dump(std::string& dump) { @@ -622,6 +627,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) { @@ -658,7 +665,19 @@ 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; + } + return mCurrentMouseDisplayId.isValid() ? mCurrentMouseDisplayId : mTopology.primaryDisplayId; } std::pair<ui::LogicalDisplayId, PointerControllerInterface&> @@ -767,7 +786,7 @@ 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(mCurrentMouseDisplayId); it != mMousePointersByDisplay.end()) { const auto& pointerController = it->second; // Use the displayId from the pointerController, because it accurately reflects whether @@ -784,12 +803,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 @@ -957,6 +980,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 = @@ -985,97 +1013,66 @@ PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusContr return ConstructorDelegate(std::move(ctor)); } -void PointerChoreographer::populateFakeDisplayTopologyLocked( - const std::vector<gui::DisplayInfo>& displayInfos) { - if (!com::android::input::flags::connected_displays_cursor()) { - return; - } - - if (displayInfos.size() == mTopology.size()) { - bool displaysChanged = false; - for (const auto& displayInfo : displayInfos) { - if (mTopology.find(displayInfo.displayId) == mTopology.end()) { - displaysChanged = true; - break; - } - } - - if (!displaysChanged) { - return; - } - } - - // create a fake topology assuming following order - // default-display (top-edge) -> next-display (right-edge) -> next-display (right-edge) ... - // This also adds a 100px offset on corresponding edge for better manual testing - // ┌────────┐ - // │ next ├─────────┐ - // ┌─└───────┐┤ next 2 │ ... - // │ default │└─────────┘ - // └─────────┘ - mTopology.clear(); - - // treat default display as base, in real topology it should be the primary-display - ui::LogicalDisplayId previousDisplay = ui::LogicalDisplayId::DEFAULT; - for (const auto& displayInfo : displayInfos) { - if (displayInfo.displayId == ui::LogicalDisplayId::DEFAULT) { - continue; - } - if (previousDisplay == ui::LogicalDisplayId::DEFAULT) { - mTopology[previousDisplay].push_back( - {displayInfo.displayId, DisplayPosition::TOP, 100}); - mTopology[displayInfo.displayId].push_back( - {previousDisplay, DisplayPosition::BOTTOM, -100}); - } else { - mTopology[previousDisplay].push_back( - {displayInfo.displayId, DisplayPosition::RIGHT, 100}); - mTopology[displayInfo.displayId].push_back( - {previousDisplay, DisplayPosition::LEFT, -100}); - } - previousDisplay = displayInfo.displayId; - } - - // update default pointer display. In real topology it should be the primary-display - if (mTopology.find(mDefaultMouseDisplayId) == mTopology.end()) { - mDefaultMouseDisplayId = ui::LogicalDisplayId::DEFAULT; - } -} - -std::optional<std::pair<const DisplayViewport*, float /*offset*/>> +std::optional<std::pair<const DisplayViewport*, float /*offsetPx*/>> PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId sourceDisplayId, - const DisplayPosition sourceBoundary, - float cursorOffset) const { - const auto& sourceNode = mTopology.find(sourceDisplayId); - if (sourceNode == mTopology.end()) { + const DisplayTopologyPosition sourceBoundary, + 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 LOG(WARNING) << "Source display missing from topology " << sourceDisplayId; return std::nullopt; } - for (const AdjacentDisplay& adjacentDisplay : sourceNode->second) { + for (const DisplayTopologyAdjacentDisplay& adjacentDisplay : sourceNode->second) { 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 == DisplayPosition::TOP || sourceBoundary == DisplayPosition::BOTTOM - ? (destinationViewport->logicalRight - destinationViewport->logicalLeft) - : (destinationViewport->logicalBottom - destinationViewport->logicalTop); - if (cursorOffset >= adjacentDisplay.offsetPx && - cursorOffset <= adjacentDisplay.offsetPx + edgeSize) { - return std::make_pair(destinationViewport, adjacentDisplay.offsetPx); + // 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 + ? (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( @@ -1093,7 +1090,6 @@ void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfo mPrivacySensitiveDisplays = std::move(newPrivacySensitiveDisplays); mPointerChoreographer->onPrivacySensitiveDisplaysChangedLocked(mPrivacySensitiveDisplays); } - mPointerChoreographer->populateFakeDisplayTopologyLocked(windowInfosUpdate.displayInfos); } void PointerChoreographer::PointerChoreographerDisplayInfoListener::setInitialDisplayInfosLocked( diff --git a/services/inputflinger/PointerChoreographer.h b/services/inputflinger/PointerChoreographer.h index 939529f774..67bdca1bab 100644 --- a/services/inputflinger/PointerChoreographer.h +++ b/services/inputflinger/PointerChoreographer.h @@ -22,6 +22,7 @@ #include <android-base/thread_annotations.h> #include <gui/WindowInfosListener.h> +#include <input/DisplayTopologyGraph.h> #include <type_traits> #include <unordered_set> @@ -80,10 +81,20 @@ public: */ virtual void setFocusedDisplay(ui::LogicalDisplayId displayId) = 0; + /* + * Used by InputManager to notify changes in the DisplayTopology + */ + virtual void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) = 0; + /** * 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 { @@ -103,6 +114,8 @@ public: ui::LogicalDisplayId displayId, DeviceId deviceId) override; 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; @@ -113,24 +126,6 @@ public: void notifyDeviceReset(const NotifyDeviceResetArgs& args) override; void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override; - // TODO(b/362719483) remove these when real topology is available - enum class DisplayPosition { - RIGHT, - TOP, - LEFT, - BOTTOM, - ftl_last = BOTTOM, - }; - - struct AdjacentDisplay { - ui::LogicalDisplayId displayId; - DisplayPosition position; - float offsetPx; - }; - void setDisplayTopology( - const std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>>& - displayTopology); - void dump(std::string& dump) override; private: @@ -174,18 +169,20 @@ private: void handleUnconsumedDeltaLocked(PointerControllerInterface& pc, const vec2& unconsumedDelta) REQUIRES(getLock()); - void populateFakeDisplayTopologyLocked(const std::vector<gui::DisplayInfo>& displayInfos) - REQUIRES(getLock()); - - std::optional<std::pair<const DisplayViewport*, float /*offset*/>> findDestinationDisplayLocked( - const ui::LogicalDisplayId sourceDisplayId, const DisplayPosition sourceBoundary, - float cursorOffset) const REQUIRES(getLock()); + std::optional<std::pair<const DisplayViewport*, float /*offsetPx*/>> + findDestinationDisplayLocked(const ui::LogicalDisplayId sourceDisplayId, + const DisplayTopologyPosition sourceBoundary, + int32_t sourceCursorOffsetPx) const REQUIRES(getLock()); - static vec2 calculateDestinationPosition(const DisplayViewport& destinationViewport, - float pointerOffset, DisplayPosition sourceBoundary); + vec2 filterPointerMotionForAccessibilityLocked(const vec2& current, const vec2& delta, + const ui::LogicalDisplayId& displayId) + REQUIRES(getLock()); - std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>> mTopology - GUARDED_BY(getLock()); + /* Topology is initialized with default-constructed value, which is an empty topology. Till we + * receive setDisplayTopology call. + * Meanwhile Choreographer will treat every display as independent disconnected display. + */ + DisplayTopologyGraph mTopology GUARDED_BY(getLock()); /* This listener keeps tracks of visible privacy sensitive displays and updates the * choreographer if there are any changes. @@ -234,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 4c1dffaf2c..ef50fc0036 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> @@ -46,6 +47,7 @@ #include <ctime> #include <queue> #include <sstream> +#include <variant> #include "../InputDeviceMetricsSource.h" @@ -417,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); } @@ -438,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++) { @@ -787,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) { @@ -924,6 +888,38 @@ Error<EnumErrorWrapper<InputEventInjectionResult>> injectionError(InputEventInje std::forward<InputEventInjectionResult>(e)); } +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& rawTransform, + std::optional<nsecs_t> firstDownTimeInTarget) { + LOG_ALWAYS_FATAL_IF(connection == nullptr); + InputTarget inputTarget{connection}; + inputTarget.windowHandle = windowHandle; + inputTarget.dispatchMode = dispatchMode; + inputTarget.flags = targetFlags; + inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor; + 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 --- @@ -934,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), @@ -954,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); @@ -976,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() { @@ -1098,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; @@ -1128,7 +1127,7 @@ std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked( if (connection->monitor) { return mMonitorDispatchingTimeout; } - const sp<WindowInfoHandle> window = getWindowHandleLocked(connection->getToken()); + const sp<WindowInfoHandle> window = mWindowInfos.findWindowHandle(connection->getToken()); if (window != nullptr) { return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT); } @@ -1147,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; } @@ -1259,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) { @@ -1333,7 +1326,7 @@ bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEnt const bool isStylus = isPointerFromStylus(motionEntry, /*pointerIndex=*/0); sp<WindowInfoHandle> touchedWindowHandle = - findTouchedWindowAtLocked(displayId, x, y, isStylus); + mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus); if (touchedWindowHandle != nullptr && touchedWindowHandle->getApplicationToken() != mAwaitedFocusedApplication->getApplicationToken()) { @@ -1346,10 +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 = - findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus, motionEntry.deviceId); + 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. @@ -1452,34 +1446,34 @@ void InputDispatcher::addRecentEventLocked(std::shared_ptr<const EventEntry> ent } } -sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(ui::LogicalDisplayId displayId, - float x, float y, bool isStylus, - bool ignoreDragWindow) const { +sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findTouchedWindowAt( + ui::LogicalDisplayId displayId, float x, float y, bool isStylus, + const sp<android::gui::WindowInfoHandle> ignoreWindow) const { // Traverse windows from front to back to find touched window. - const auto& windowHandles = getWindowHandlesLocked(displayId); + const auto& windowHandles = getWindowHandlesForDisplay(displayId); for (const sp<WindowInfoHandle>& windowHandle : windowHandles) { - if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) { + if (ignoreWindow && haveSameToken(windowHandle, ignoreWindow)) { continue; } const WindowInfo& info = *windowHandle->getInfo(); if (!info.isSpy() && - windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) { + windowAcceptsTouchAt(info, displayId, x, y, isStylus, getDisplayTransform(displayId))) { return windowHandle; } } 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 {}; } // Traverse windows from front to back until we encounter the touched window. std::vector<InputTarget> outsideTargets; - const auto& windowHandles = getWindowHandlesLocked(displayId); + const auto& windowHandles = mWindowInfos.getWindowHandlesForDisplay(displayId); for (const sp<WindowInfoHandle>& windowHandle : windowHandles) { if (windowHandle == touchedWindow) { // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window @@ -1491,36 +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::findTouchedSpyWindowsAtLocked( - ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId) const { +std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAt( + ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId, + const DispatcherWindowInfo& windowInfos) { // Traverse windows from front to back and gather the touched spy windows. std::vector<sp<WindowInfoHandle>> spyWindows; - const auto& windowHandles = getWindowHandlesLocked(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, getTransformLocked(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 (!windowHasTouchingPointersLocked(windowHandle, deviceId)) { - 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. @@ -1535,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: @@ -1651,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) { @@ -1693,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) { @@ -1710,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; } @@ -1742,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 } @@ -1810,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; @@ -1828,7 +1807,7 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked( void InputDispatcher::dispatchTouchModeChangeLocked( nsecs_t currentTime, const std::shared_ptr<const TouchModeEntry>& entry) { const std::vector<sp<WindowInfoHandle>>& windowHandles = - getWindowHandlesLocked(entry->displayId); + mWindowInfos.getWindowHandlesForDisplay(entry->displayId); if (windowHandles.empty()) { return; } @@ -1849,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 } @@ -1889,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(); } @@ -1988,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); @@ -2020,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); @@ -2073,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); @@ -2142,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 } @@ -2183,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); @@ -2216,7 +2199,7 @@ void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection> sp<WindowInfoHandle> windowHandle; if (!connection->monitor) { - windowHandle = getWindowHandleLocked(connection->getToken()); + windowHandle = mWindowInfos.findWindowHandle(connection->getToken()); if (windowHandle == nullptr) { // The window that is receiving this ANR was removed, so there is no need to generate // cancellations, because the cancellations would have already been generated when @@ -2228,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; @@ -2317,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); } @@ -2386,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; @@ -2418,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 || @@ -2440,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. @@ -2472,25 +2431,14 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down. const bool isStylus = isPointerFromStylus(entry, pointerIndex); sp<WindowInfoHandle> newTouchedWindowHandle = - findTouchedWindowAtLocked(displayId, x, y, isStylus); + 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) { @@ -2498,27 +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 = - findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus, entry.deviceId); + 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); @@ -2531,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; } @@ -2542,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. @@ -2574,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 @@ -2585,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 | @@ -2623,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); } @@ -2644,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 && @@ -2655,7 +2571,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio tempTouchState.getFirstForegroundWindowHandle(entry.deviceId); LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr); sp<WindowInfoHandle> newTouchedWindowHandle = - findTouchedWindowAtLocked(displayId, x, y, isStylus); + mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus); // Verify targeted injection. if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) { @@ -2665,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; } @@ -2682,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, @@ -2713,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); } @@ -2726,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)) { @@ -2740,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); } } @@ -2779,7 +2680,7 @@ InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const Motio for (InputTarget& target : targets) { if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) { sp<WindowInfoHandle> targetWindow = - getWindowHandleLocked(target.connection->getToken()); + mWindowInfos.findWindowHandle(target.connection->getToken()); if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) { target.flags |= InputTarget::Flags::ZERO_COORDS; } @@ -2803,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 @@ -2860,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; } @@ -2879,7 +2777,8 @@ void InputDispatcher::finishDragAndDrop(ui::LogicalDisplayId displayId, float x, constexpr bool isStylus = false; sp<WindowInfoHandle> dropWindow = - findTouchedWindowAtLocked(displayId, x, y, isStylus, /*ignoreDragWindow=*/true); + mWindowInfos.findTouchedWindowAt(displayId, x, y, isStylus, /*ignoreWindow=*/ + mDragState->dragWindow); if (dropWindow) { vec2 local = dropWindow->getInfo()->transform.transform(x, y); sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y); @@ -2891,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; } @@ -2934,8 +2834,8 @@ void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { constexpr bool isStylus = false; sp<WindowInfoHandle> hoverWindowHandle = - findTouchedWindowAtLocked(entry.displayId, x, y, isStylus, - /*ignoreDragWindow=*/true); + mWindowInfos.findTouchedWindowAt(entry.displayId, x, y, isStylus, + /*ignoreWindow=*/mDragState->dragWindow); // enqueue drag exit if needed. if (hoverWindowHandle != mDragState->dragHoverWindowHandle && !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) { @@ -2970,31 +2870,6 @@ void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { } } -std::optional<InputTarget> InputDispatcher::createInputTargetLocked( - const sp<android::gui::WindowInfoHandle>& windowHandle, - InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags, - std::optional<nsecs_t> firstDownTimeInTarget) const { - std::shared_ptr<Connection> connection = getConnectionLocked(windowHandle->getToken()); - if (connection == nullptr) { - ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str()); - return {}; - } - InputTarget inputTarget{connection}; - inputTarget.windowHandle = windowHandle; - inputTarget.dispatchMode = dispatchMode; - inputTarget.flags = targetFlags; - inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor; - inputTarget.firstDownTimeInTarget = firstDownTimeInTarget; - const auto& displayInfoIt = mDisplayInfos.find(windowHandle->getInfo()->displayId); - if (displayInfoIt != mDisplayInfos.end()) { - inputTarget.displayTransform = displayInfoIt->second.transform; - } else { - // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId. - // TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed. - } - return inputTarget; -} - void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle, InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags, @@ -3009,13 +2884,17 @@ void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHa const WindowInfo* windowInfo = windowHandle->getInfo(); if (it == inputTargets.end()) { - std::optional<InputTarget> target = - createInputTargetLocked(windowHandle, dispatchMode, targetFlags, - firstDownTimeInTarget); - if (!target) { + 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(*target); + inputTargets.push_back( + createInputTarget(connection, windowHandle, dispatchMode, targetFlags, + mWindowInfos.getRawTransform(*windowHandle->getInfo()), + firstDownTimeInTarget)); it = inputTargets.end() - 1; } @@ -3028,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; @@ -3057,16 +2937,19 @@ void InputDispatcher::addPointerWindowTargetLocked( it = inputTargets.end(); } - const WindowInfo* windowInfo = windowHandle->getInfo(); + const WindowInfo& windowInfo = *windowHandle->getInfo(); if (it == inputTargets.end()) { - std::optional<InputTarget> target = - createInputTargetLocked(windowHandle, dispatchMode, targetFlags, - firstDownTimeInTarget); - if (!target) { + std::shared_ptr<Connection> connection = mConnectionManager.getConnection(windowInfo.token); + if (connection == nullptr) { + ALOGW("Not creating InputTarget for %s, no input channel", windowInfo.name.c_str()); return; } - inputTargets.push_back(*target); + inputTargets.push_back( + createInputTarget(connection, windowHandle, dispatchMode, targetFlags, + mWindowInfos.getRawTransform(*windowHandle->getInfo(), + pointerDisplayId), + firstDownTimeInTarget)); it = inputTargets.end() - 1; } @@ -3078,33 +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 - if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) { - target.displayTransform = it->second.transform; - } - 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); + }); } /** @@ -3160,11 +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 = getWindowHandlesLocked(displayId); + const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId); TouchOcclusionInfo info; info.hasBlockingOcclusion = false; info.obscuringOpacity = 0; @@ -3176,11 +3071,11 @@ InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLo } const WindowInfo* otherInfo = otherHandle->getInfo(); if (canBeObscuredBy(windowHandle, otherHandle) && - windowOccludesTouchAt(*otherInfo, displayId, x, y, getTransformLocked(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 @@ -3208,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()); @@ -3245,26 +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 = getWindowHandlesLocked(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, getTransformLocked(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 = getWindowHandlesLocked(displayId); + const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId); const WindowInfo* windowInfo = windowHandle->getInfo(); for (const sp<WindowInfoHandle>& otherHandle : windowHandles) { if (windowHandle == otherHandle) { @@ -3330,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; @@ -3347,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; @@ -3378,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; } @@ -3512,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; } @@ -3810,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(); @@ -3827,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 @@ -3849,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) { @@ -3921,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; } @@ -3995,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; @@ -4011,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); @@ -4059,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); @@ -4118,7 +3986,8 @@ int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionTok } else { // Monitor channels are never explicitly unregistered. // We do it automatically when the remote endpoint is closed so don't warn about them. - const bool stillHaveWindowHandle = getWindowHandleLocked(connection->getToken()) != nullptr; + const bool stillHaveWindowHandle = + mWindowInfos.findWindowHandle(connection->getToken()) != nullptr; notify = !connection->monitor && stillHaveWindowHandle; if (notify) { ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x", @@ -4127,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 } @@ -4141,23 +4010,27 @@ 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 // the windows that have an ongoing focus event stream. if (cancelNonPointers) { - for (const auto& [_, handles] : mWindowHandlesByDisplay) { - for (const auto& windowHandle : handles) { - synthesizeCancelationEventsForWindowLocked(windowHandle, options); - } - } + mWindowInfos.forEachWindowHandle( + [&](const sp<android::gui::WindowInfoHandle>& windowHandle) { + base::ScopedLockAssertion assumeLocked(mLock); + synthesizeCancelationEventsForWindowLocked(windowHandle, options); + }); } // Cancel monitors. @@ -4166,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( @@ -4189,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; @@ -4218,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) @@ -4276,16 +4148,22 @@ 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); - const auto it = mDisplayInfos.find(motionEntry.displayId); - if (it != mDisplayInfos.end()) { - targets.back().displayTransform = it->second.transform; - targets.back().setDefaultPointerTransform(it->second.transform); - } + // 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().rawTransform = displayTransform; + targets.back().setDefaultPointerTransform(displayTransform); } logOutboundMotionDetails("cancel - ", motionEntry); break; @@ -4334,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] = - findTouchStateWindowAndDisplayLocked(connection->getToken()); - 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) { @@ -4362,16 +4235,21 @@ 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); - const auto it = mDisplayInfos.find(motionEntry.displayId); - if (it != mDisplayInfos.end()) { - targets.back().displayTransform = it->second.transform; - targets.back().setDefaultPointerTransform(it->second.transform); - } + // 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().rawTransform = displayTransform; + targets.back().setDefaultPointerTransform(displayTransform); } logOutboundMotionDetails("down - ", motionEntry); break; @@ -4471,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(); @@ -4607,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(); } @@ -4631,21 +4510,13 @@ 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; } } if (shouldSendMotionToInputFilterLocked(args)) { - ui::Transform displayTransform; - if (const auto it = mDisplayInfos.find(args.displayId); it != mDisplayInfos.end()) { - displayTransform = it->second.transform; - } + ui::Transform displayTransform = mWindowInfos.getDisplayTransform(args.displayId); mLock.unlock(); @@ -4696,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 @@ -4723,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); } @@ -4735,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; @@ -4748,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 @@ -4772,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 @@ -4812,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(); @@ -4834,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; @@ -4931,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, @@ -4942,13 +4809,8 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev 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. - const auto touchStateIt = mTouchStatesByDisplay.find(displayId); - if (touchStateIt != mTouchStatesByDisplay.end()) { - const TouchState& touchState = touchStateIt->second; - if (touchState.hasTouchingPointers(resolvedDeviceId) || - touchState.hasHoveringPointers(resolvedDeviceId)) { - policyFlags |= POLICY_FLAG_PASS_TO_USER; - } + if (mTouchStates.hasTouchingOrHoveringPointers(displayId, resolvedDeviceId)) { + policyFlags |= POLICY_FLAG_PASS_TO_USER; } } @@ -5017,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(); } @@ -5045,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; } @@ -5059,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; } @@ -5079,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; } @@ -5128,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. @@ -5162,9 +5014,8 @@ void InputDispatcher::transformMotionEntryForInjectionLocked( MotionEntry& entry, const ui::Transform& injectedTransform) const { // Input injection works in the logical display coordinate space, but the input pipeline works // display space, so we need to transform the injected events accordingly. - const auto it = mDisplayInfos.find(entry.displayId); - if (it == mDisplayInfos.end()) return; - const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform; + const ui::Transform displayTransform = mWindowInfos.getDisplayTransform(entry.displayId); + const auto& transformToDisplay = displayTransform.inverse() * injectedTransform; if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION && entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) { @@ -5197,14 +5048,7 @@ void InputDispatcher::decrementPendingForegroundDispatches(const EventEntry& ent } } -const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked( - ui::LogicalDisplayId displayId) const { - static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES; - auto it = mWindowHandlesByDisplay.find(displayId); - return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES; -} - -sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked( +sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWindowHandle( const sp<IBinder>& windowHandleToken, std::optional<ui::LogicalDisplayId> displayId) const { if (windowHandleToken == nullptr) { return nullptr; @@ -5223,15 +5067,26 @@ sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked( } // Only look through the requested display. - for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(*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; } } return nullptr; } -sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked( +bool InputDispatcher::DispatcherWindowInfo::isWindowPresent( const sp<WindowInfoHandle>& windowHandle) const { for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) { for (const sp<WindowInfoHandle>& handle : windowHandles) { @@ -5243,27 +5098,159 @@ sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked( windowHandle->getName().c_str(), displayId.toString().c_str(), windowHandle->getInfo()->displayId.toString().c_str()); } - return handle; + return true; } } } - return nullptr; + return false; } sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked( ui::LogicalDisplayId displayId) const { sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId); - return getWindowHandleLocked(focusedToken, displayId); + return mWindowInfos.findWindowHandle(focusedToken, displayId); } -ui::Transform InputDispatcher::getTransformLocked(ui::LogicalDisplayId displayId) const { +void InputDispatcher::DispatcherWindowInfo::setWindowHandlesForDisplay( + ui::LogicalDisplayId displayId, std::vector<sp<WindowInfoHandle>>&& windowHandles) { + // Insert or replace + mWindowHandlesByDisplay[displayId] = std::move(windowHandles); +} + +void InputDispatcher::DispatcherWindowInfo::setDisplayInfos( + const std::vector<android::gui::DisplayInfo>& displayInfos) { + mDisplayInfos.clear(); + for (const auto& displayInfo : displayInfos) { + mDisplayInfos.emplace(displayInfo.displayId, displayInfo); + } +} + +void InputDispatcher::DispatcherWindowInfo::removeDisplay(ui::LogicalDisplayId displayId) { + mWindowHandlesByDisplay.erase(displayId); +} + +const std::vector<sp<android::gui::WindowInfoHandle>>& +InputDispatcher::DispatcherWindowInfo::getWindowHandlesForDisplay( + ui::LogicalDisplayId displayId) const { + static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES; + const auto it = mWindowHandlesByDisplay.find(displayId); + return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES; +} + +void InputDispatcher::DispatcherWindowInfo::forEachWindowHandle( + std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const { + for (const auto& [_, windowHandles] : mWindowHandlesByDisplay) { + for (const auto& windowHandle : windowHandles) { + f(windowHandle); + } + } +} + +void InputDispatcher::DispatcherWindowInfo::forEachDisplayId( + std::function<void(ui::LogicalDisplayId)> f) const { + for (const auto& [displayId, _] : mWindowHandlesByDisplay) { + f(displayId); + } +} + +ui::Transform InputDispatcher::DispatcherWindowInfo::getDisplayTransform( + ui::LogicalDisplayId displayId) const { auto displayInfoIt = mDisplayInfos.find(displayId); return displayInfoIt != mDisplayInfos.end() ? displayInfoIt->second.transform : kIdentityTransform; } -bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window, - const MotionEntry& motionEntry) const { +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()) { + for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) { + dump += StringPrintf("Display: %s\n", displayId.toString().c_str()); + if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) { + const auto& displayInfo = it->second; + dump += StringPrintf(INDENT "logicalSize=%dx%d\n", displayInfo.logicalWidth, + displayInfo.logicalHeight); + displayInfo.transform.dump(dump, "transform", INDENT3); + } else { + dump += INDENT "No DisplayInfo found!\n"; + } + + if (!windowHandles.empty()) { + dump += INDENT "Windows:\n"; + for (size_t i = 0; i < windowHandles.size(); i++) { + dump += StringPrintf(INDENT2 "%zu: %s", i, + streamableToString(*windowHandles[i]).c_str()); + } + } else { + dump += INDENT "Windows: <none>\n"; + } + } + } else { + dump += "Displays: <none>\n"; + } + return dump; +} + +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. @@ -5282,7 +5269,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()); @@ -5296,8 +5283,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) { @@ -5310,13 +5298,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; } @@ -5329,13 +5317,14 @@ void InputDispatcher::updateWindowHandlesForDisplayLocked( ui::LogicalDisplayId displayId) { if (windowInfoHandles.empty()) { // Remove all handles on a display if there are no windows left. - mWindowHandlesByDisplay.erase(displayId); + mWindowInfos.removeDisplay(displayId); return; } // Since we compare the pointer of input window handles across window updates, we need // to make sure the handle object for the same window stays unchanged across updates. - const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId); + const std::vector<sp<WindowInfoHandle>>& oldHandles = + mWindowInfos.getWindowHandlesForDisplay(displayId); std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById; for (const sp<WindowInfoHandle>& handle : oldHandles) { oldHandlesById[handle->getId()] = handle; @@ -5344,7 +5333,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 = @@ -5374,8 +5363,7 @@ void InputDispatcher::updateWindowHandlesForDisplayLocked( } } - // Insert or replace - mWindowHandlesByDisplay[displayId] = newHandles; + mWindowInfos.setWindowHandlesForDisplay(displayId, std::move(newHandles)); } /** @@ -5425,12 +5413,14 @@ void InputDispatcher::setInputWindowsLocked( } // Copy old handles for release if they are no longer present. - const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId); + const std::vector<sp<WindowInfoHandle>> oldWindowHandles = + mWindowInfos.getWindowHandlesForDisplay(displayId); const sp<WindowInfoHandle> removedFocusedWindowHandle = getFocusedWindowHandleLocked(displayId); updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId); - const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId); + const std::vector<sp<WindowInfoHandle>>& windowHandles = + mWindowInfos.getWindowHandlesForDisplay(displayId); std::optional<FocusResolver::FocusChanges> changes = mFocusResolver.setInputWindows(displayId, windowHandles); @@ -5438,69 +5428,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 (getWindowHandleLocked(touchedWindow.windowHandle) != nullptr) { - 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 = getTransformLocked(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. @@ -5508,22 +5467,87 @@ void InputDispatcher::setInputWindowsLocked( // Otherwise, they might stick around until the window handle is destroyed // which might not happen until the next GC. for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) { - if (getWindowHandleLocked(oldWindowHandle) == nullptr) { - if (DEBUG_FOCUS) { - ALOGD("Window went away: %s", oldWindowHandle->getName().c_str()); - } + if (!mWindowInfos.isWindowPresent(oldWindowHandle)) { + 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); @@ -5573,9 +5597,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); @@ -5585,7 +5607,7 @@ void InputDispatcher::setFocusedDisplay(ui::LogicalDisplayId displayId) { mFocusResolver.getFocusedWindowToken(mFocusedDisplayId); if (oldFocusedWindowToken != nullptr) { const auto windowHandle = - getWindowHandleLocked(oldFocusedWindowToken, mFocusedDisplayId); + mWindowInfos.findWindowHandle(oldFocusedWindowToken, mFocusedDisplayId); if (windowHandle == nullptr) { LOG(FATAL) << __func__ << ": Previously focused token did not have a window"; } @@ -5629,9 +5651,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 @@ -5661,9 +5682,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); @@ -5685,14 +5704,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) { @@ -5724,7 +5745,7 @@ bool InputDispatcher::focusedWindowIsOwnedByLocked(gui::Pid pid, gui::Uid uid) { if (focusedToken == nullptr) { return false; } - sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken); + sp<WindowInfoHandle> windowHandle = mWindowInfos.findWindowHandle(focusedToken); return isWindowOwnedBy(windowHandle, pid, uid); } @@ -5732,105 +5753,52 @@ bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid) return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(), [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) { const sp<WindowInfoHandle> windowHandle = - getWindowHandleLocked(connectionToken); + mWindowInfos.findWindowHandle(connectionToken); return isWindowOwnedBy(windowHandle, pid, uid); }) != mInteractionConnectionTokens.end(); } 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<TouchState*, TouchedWindow*, ui::LogicalDisplayId> -InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) { - for (auto& [displayId, state] : mTouchStatesByDisplay) { - for (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<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId> -InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) const { - return const_cast<InputDispatcher*>(this)->findTouchStateWindowAndDisplayLocked(token); -} - -bool InputDispatcher::windowHasTouchingPointersLocked(const sp<WindowInfoHandle>& windowHandle, - DeviceId deviceId) const { - const auto& [touchState, touchedWindow, _] = - findTouchStateWindowAndDisplayLocked(windowHandle->getToken()); - 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] = findTouchStateWindowAndDisplayLocked(fromToken); + 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."); - 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(); + auto result = mTouchStates.transferTouchGesture(fromToken, toToken); + if (!result.has_value()) { return false; } - const DeviceId deviceId = *deviceIds.begin(); - const sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle; - const sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(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) { @@ -5843,30 +5811,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. @@ -5874,33 +5818,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::findTouchedForegroundWindowLocked( +sp<WindowInfoHandle> InputDispatcher::DispatcherTouchState::findTouchedForegroundWindow( ui::LogicalDisplayId displayId) const { - auto stateIt = mTouchStatesByDisplay.find(displayId); - if (stateIt == mTouchStatesByDisplay.end()) { - ALOGI("No touch state on display %s", displayId.toString().c_str()); - return nullptr; - } - - const TouchState& state = stateIt->second; 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; } @@ -5910,14 +5931,15 @@ bool InputDispatcher::transferTouchOnDisplay(const sp<IBinder>& destChannelToken sp<IBinder> fromToken; { // acquire lock std::scoped_lock _l(mLock); - sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId); + sp<WindowInfoHandle> toWindowHandle = + mWindowInfos.findWindowHandle(destChannelToken, displayId); if (toWindowHandle == nullptr) { ALOGW("Could not find window associated with token=%p on display %s", destChannelToken.get(), displayId.toString().c_str()); return false; } - sp<WindowInfoHandle> from = findTouchedForegroundWindowLocked(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; @@ -5930,9 +5952,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, @@ -5945,7 +5965,7 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { resetNoFocusedWindowTimeoutLocked(); mAnrTracker.clear(); - mTouchStatesByDisplay.clear(); + mTouchStates.clear(); } void InputDispatcher::logDispatchStateLocked() const { @@ -5969,7 +5989,7 @@ std::string InputDispatcher::dumpPointerCaptureStateLocked() const { std::string windowName = "None"; if (mWindowTokenWithPointerCapture) { const sp<WindowInfoHandle> captureWindowHandle = - getWindowHandleLocked(mWindowTokenWithPointerCapture); + mWindowInfos.findWindowHandle(mWindowTokenWithPointerCapture); windowName = captureWindowHandle ? captureWindowHandle->getName().c_str() : "token has capture without window"; } @@ -6003,59 +6023,19 @@ 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"); mDragState->dump(dump, INDENT2); } - if (!mWindowHandlesByDisplay.empty()) { - for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) { - dump += StringPrintf(INDENT "Display: %s\n", displayId.toString().c_str()); - if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) { - const auto& displayInfo = it->second; - dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth, - displayInfo.logicalHeight); - displayInfo.transform.dump(dump, "transform", INDENT4); - } else { - dump += INDENT2 "No DisplayInfo found!\n"; - } - - if (!windowHandles.empty()) { - dump += INDENT2 "Windows:\n"; - for (size_t i = 0; i < windowHandles.size(); i++) { - dump += StringPrintf(INDENT3 "%zu: %s", i, - streamableToString(*windowHandles[i]).c_str()); - } - } else { - dump += INDENT2 "Windows: <none>\n"; - } - } - } else { - dump += INDENT "Displays: <none>\n"; - } - - 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"; - } + dump += addLinePrefix(mWindowInfos.dumpDisplayAndWindowInfo(), INDENT); 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()); @@ -6097,37 +6077,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) { @@ -6148,16 +6097,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) {} @@ -6168,9 +6107,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; @@ -6183,21 +6120,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. @@ -6223,23 +6149,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. @@ -6250,8 +6164,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; } @@ -6263,30 +6183,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); - } + LOG_ALWAYS_FATAL_IF(connection == nullptr); + abortBrokenDispatchCycleLocked(connection, notify); - mLooper->removeFd(connection->inputPublisher.getChannel().getFd()); - - 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) { @@ -6307,49 +6215,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] = findTouchStateWindowAndDisplayLocked(token); - 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; @@ -6359,14 +6288,14 @@ 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) { { // acquire lock std::scoped_lock _l(mLock); if (DEBUG_FOCUS) { - const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken); + const sp<WindowInfoHandle> windowHandle = mWindowInfos.findWindowHandle(windowToken); ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable", windowHandle != nullptr ? windowHandle->getName().c_str() : "token without window"); @@ -6413,7 +6342,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) { @@ -6424,7 +6354,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; @@ -6439,19 +6369,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, @@ -6506,17 +6423,17 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime, } traceWaitQueueLength(*connection); if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) { - const auto windowHandle = getWindowHandleLocked(connection->getToken()); + const auto windowHandle = mWindowInfos.findWindowHandle(connection->getToken()); // Only dispatch fallbacks if there is a window for the connection. if (windowHandle != nullptr) { - const auto inputTarget = - createInputTargetLocked(windowHandle, InputTarget::DispatchMode::AS_IS, - dispatchEntry->targetFlags, - fallbackKeyEntry->downTime); - if (inputTarget.has_value()) { - enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry), - *inputTarget); - } + nsecs_t downTime = fallbackKeyEntry->downTime; + enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry), + createInputTarget(connection, windowHandle, + InputTarget::DispatchMode::AS_IS, + dispatchEntry->targetFlags, + mWindowInfos.getRawTransform( + *windowHandle->getInfo()), + downTime)); } } releaseDispatchEntry(std::move(dispatchEntry)); @@ -6570,7 +6487,7 @@ void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection) ns2ms(currentWait), oldestEntry.eventEntry->getDescription().c_str()); sp<IBinder> connectionToken = connection->getToken(); - updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason); + updateLastAnrStateLocked(mWindowInfos.findWindowHandle(connectionToken), reason); processConnectionUnresponsiveLocked(*connection, std::move(reason)); @@ -6621,24 +6538,27 @@ void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel, void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken, const KeyEntry& entry) { const KeyEvent event = createKeyEvent(entry); + std::variant<nsecs_t, KeyEntry::InterceptKeyResult> interceptResult; nsecs_t delay = 0; { // release lock scoped_unlock unlock(mLock); android::base::Timer t; - delay = mPolicy.interceptKeyBeforeDispatching(focusedWindowToken, event, entry.policyFlags); + interceptResult = + mPolicy.interceptKeyBeforeDispatching(focusedWindowToken, event, entry.policyFlags); if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) { ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms", std::to_string(t.duration().count()).c_str()); } } // acquire lock - if (delay < 0) { - entry.interceptKeyResult = KeyEntry::InterceptKeyResult::SKIP; - } else if (delay == 0) { - entry.interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE; - } else { + if (std::holds_alternative<KeyEntry::InterceptKeyResult>(interceptResult)) { + entry.interceptKeyResult = std::get<KeyEntry::InterceptKeyResult>(interceptResult); + return; + } + + if (std::holds_alternative<nsecs_t>(interceptResult)) { entry.interceptKeyResult = KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER; - entry.interceptKeyWakeupTime = now() + delay; + entry.interceptKeyWakeupTime = now() + std::get<nsecs_t>(interceptResult); } } @@ -6673,12 +6593,12 @@ 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(), reason.c_str()); - const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken); + const sp<WindowInfoHandle> handle = mWindowInfos.findWindowHandle(connectionToken); if (handle != nullptr) { pid = handle->getInfo()->ownerPid; } @@ -6693,10 +6613,10 @@ 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 = getWindowHandleLocked(connectionToken); + const sp<WindowInfoHandle> handle = mWindowInfos.findWindowHandle(connectionToken); if (handle != nullptr) { pid = handle->getInfo()->ownerPid; } @@ -6738,12 +6658,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); @@ -6761,7 +6680,7 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl // Cancel the fallback key, but only if we still have a window for the channel. // It could have been removed during the policy call. if (*fallbackKeyCode != AKEYCODE_UNKNOWN) { - const auto windowHandle = getWindowHandleLocked(connection->getToken()); + const auto windowHandle = mWindowInfos.findWindowHandle(connection->getToken()); if (windowHandle != nullptr) { CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS, "application handled the original non-fallback key " @@ -6780,21 +6699,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(); @@ -6847,7 +6767,7 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl } } - const auto windowHandle = getWindowHandleLocked(connection->getToken()); + const auto windowHandle = mWindowInfos.findWindowHandle(connection->getToken()); if (windowHandle != nullptr) { CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS, "canceling fallback, policy no longer desires it", @@ -6891,16 +6811,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); @@ -6989,7 +6906,7 @@ void InputDispatcher::setFocusedWindow(const FocusRequest& request) { std::scoped_lock _l(mLock); std::optional<FocusResolver::FocusChanges> changes = mFocusResolver.setFocusedWindow(request, - getWindowHandlesLocked( + mWindowInfos.getWindowHandlesForDisplay( ui::LogicalDisplayId{request.displayId})); ScopedSyntheticEventTracer traceContext(mTracer); if (changes) { @@ -7007,7 +6924,7 @@ void InputDispatcher::onFocusChangedLocked( if (changes.oldFocus) { const auto resolvedWindow = removedFocusedWindowHandle != nullptr ? removedFocusedWindowHandle - : getWindowHandleLocked(changes.oldFocus, changes.displayId); + : mWindowInfos.findWindowHandle(changes.oldFocus, changes.displayId); if (resolvedWindow == nullptr) { LOG(FATAL) << __func__ << ": Previously focused token did not have a window"; } @@ -7041,7 +6958,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); @@ -7111,13 +7028,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 @@ -7125,14 +7035,10 @@ void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) // Ensure that we have an entry created for all existing displays so that if a displayId has // no windows, we can tell that the windows were removed from the display. - for (const auto& [displayId, _] : mWindowHandlesByDisplay) { - handlesPerDisplay[displayId]; - } + mWindowInfos.forEachDisplayId( + [&](ui::LogicalDisplayId displayId) { handlesPerDisplay[displayId]; }); - mDisplayInfos.clear(); - for (const auto& displayInfo : update.displayInfos) { - mDisplayInfos.emplace(displayInfo.displayId, displayInfo); - } + mWindowInfos.setDisplayInfos(update.displayInfos); for (const auto& [displayId, handles] : handlesPerDisplay) { setInputWindowsLocked(handles, displayId); @@ -7149,12 +7055,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(), @@ -7179,7 +7086,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(); @@ -7190,11 +7097,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]; @@ -7207,16 +7113,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); } @@ -7228,12 +7135,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); @@ -7244,16 +7153,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) { @@ -7265,21 +7174,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 = - getWindowHandlesLocked(windowHandle->getInfo()->displayId); + getWindowHandlesForDisplay(windowHandle->getInfo()->displayId); bool foundWindow = false; for (const sp<WindowInfoHandle>& otherHandle : windowHandles) { if (!foundWindow && otherHandle != windowHandle) { @@ -7311,18 +7221,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) { @@ -7332,4 +7231,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 fade8535c3..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,45 +564,8 @@ private: // to transfer focus to a new application. std::shared_ptr<const EventEntry> mNextUnblockedEvent GUARDED_BY(mLock); - sp<android::gui::WindowInfoHandle> findTouchedWindowAtLocked( - ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false, - bool ignoreDragWindow = false) const REQUIRES(mLock); - std::vector<InputTarget> findOutsideTargetsLocked( - ui::LogicalDisplayId displayId, const sp<android::gui::WindowInfoHandle>& touchedWindow, - int32_t pointerId) const REQUIRES(mLock); - - std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAtLocked( - ui::LogicalDisplayId displayId, float x, float y, bool isStylus, - DeviceId deviceId) const REQUIRES(mLock); - - sp<android::gui::WindowInfoHandle> findTouchedForegroundWindowLocked( - ui::LogicalDisplayId displayId) const REQUIRES(mLock); - - 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; @@ -350,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, @@ -368,28 +642,12 @@ private: }; sp<gui::WindowInfosListener> mWindowInfoListener; - std::unordered_map<ui::LogicalDisplayId /*displayId*/, - std::vector<sp<android::gui::WindowInfoHandle>>> - mWindowHandlesByDisplay GUARDED_BY(mLock); - std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo> mDisplayInfos - GUARDED_BY(mLock); void setInputWindowsLocked( const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles, ui::LogicalDisplayId displayId) REQUIRES(mLock); - // Get a reference to window handles by display, return an empty vector if not found. - const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesLocked( - ui::LogicalDisplayId displayId) const REQUIRES(mLock); - ui::Transform getTransformLocked(ui::LogicalDisplayId displayId) const REQUIRES(mLock); - sp<android::gui::WindowInfoHandle> getWindowHandleLocked( - const sp<IBinder>& windowHandleToken, - std::optional<ui::LogicalDisplayId> displayId = {}) const REQUIRES(mLock); - sp<android::gui::WindowInfoHandle> getWindowHandleLocked( - const sp<android::gui::WindowInfoHandle>& windowHandle) const 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. @@ -404,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( @@ -545,26 +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); - - std::optional<InputTarget> createInputTargetLocked( - const sp<android::gui::WindowInfoHandle>& windowHandle, - InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags, - std::optional<nsecs_t> firstDownTimeInTarget) 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); @@ -573,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 @@ -618,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); @@ -659,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. @@ -695,15 +919,6 @@ private: const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry, bool handled) REQUIRES(mLock); - // Find touched state and touched window by token. - std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId> - findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) REQUIRES(mLock); - - std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId> - findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) const REQUIRES(mLock); - bool windowHasTouchingPointersLocked(const sp<android::gui::WindowInfoHandle>& windowHandle, - DeviceId deviceId) const REQUIRES(mLock); - // Statistics gathering. nsecs_t mLastStatisticPushTime = 0; std::unique_ptr<InputEventTimelineProcessor> mInputEventTimelineProcessor GUARDED_BY(mLock); @@ -718,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/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h index b885ba17f3..5dcd98419d 100644 --- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h +++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h @@ -20,12 +20,14 @@ #include <android-base/properties.h> #include <binder/IBinder.h> +#include <dispatcher/Entry.h> #include <gui/InputApplication.h> #include <gui/PidUid.h> #include <input/Input.h> #include <input/InputDevice.h> #include <utils/RefBase.h> #include <set> +#include <variant> namespace android { @@ -106,9 +108,9 @@ public: uint32_t& policyFlags) = 0; /* Allows the policy a chance to intercept a key before dispatching. */ - virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token, - const KeyEvent& keyEvent, - uint32_t policyFlags) = 0; + virtual std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> + interceptKeyBeforeDispatching(const sp<IBinder>& token, const KeyEvent& keyEvent, + uint32_t policyFlags) = 0; /* Allows the policy a chance to perform default processing for an unhandled key. * Returns an alternate key event to redispatch as a fallback, if needed. */ 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 4d6b6c7fd5..608bec4a0c 100644 --- a/services/inputflinger/include/InputReaderBase.h +++ b/services/inputflinger/include/InputReaderBase.h @@ -139,8 +139,21 @@ struct InputReaderConfiguration { // The mouse pointer speed, as a number from -7 (slowest) to 7 (fastest). int32_t mousePointerSpeed; - // Displays on which an acceleration curve shouldn't be applied for pointer movements from mice. - std::set<ui::LogicalDisplayId> displaysWithMousePointerAccelerationDisabled; + // Displays on which all pointer scaling, including linear scaling based on the + // 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> 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). @@ -274,12 +287,17 @@ 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:: DEFAULT_POINTER_ACCELERATION)), - wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f), + wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, + static_cast<float>( + android::os::IInputConstants:: + DEFAULT_MOUSE_WHEEL_ACCELERATION)), pointerGesturesEnabled(true), pointerGestureQuietInterval(100 * 1000000LL), // 100 ms pointerGestureDragMinSwitchSpeed(50), // 50 pixels per second 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..845cab05d3 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -62,6 +62,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 +196,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 +262,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 +290,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 +374,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()) { @@ -1085,7 +1109,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..0d6e1020c1 100644 --- a/services/inputflinger/reader/include/InputReader.h +++ b/services/inputflinger/reader/include/InputReader.h @@ -25,6 +25,7 @@ #include <vector> #include "EventHub.h" +#include "InputDevice.h" #include "InputListener.h" #include "InputReaderBase.h" #include "InputReaderContext.h" @@ -127,7 +128,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 @@ -154,7 +156,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) diff --git a/services/inputflinger/reader/include/InputReaderContext.h b/services/inputflinger/reader/include/InputReaderContext.h index e0e0ac2051..20ed74fef7 100644 --- a/services/inputflinger/reader/include/InputReaderContext.h +++ b/services/inputflinger/reader/include/InputReaderContext.h @@ -55,7 +55,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/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index b33659cae1..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; } @@ -481,15 +481,21 @@ void CursorInputMapper::configureOnChangePointerSpeed(const InputReaderConfigura mPointerVelocityControl.setAccelerationEnabled(false); mWheelXVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS); mWheelYVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS); - } else { - mPointerVelocityControl.setAccelerationEnabled( - config.displaysWithMousePointerAccelerationDisabled.count( - mDisplayId.value_or(ui::LogicalDisplayId::INVALID)) == 0); - mPointerVelocityControl.setCurve( - createAccelerationCurveForPointerSensitivity(config.mousePointerSpeed)); - mWheelXVelocityControl.setParameters(config.wheelVelocityControlParameters); - mWheelYVelocityControl.setParameters(config.wheelVelocityControlParameters); + return; } + + bool disableAllScaling = config.displaysWithMouseScalingDisabled.count( + mDisplayId.value_or(ui::LogicalDisplayId::INVALID)) != 0; + + mPointerVelocityControl.setAccelerationEnabled(!disableAllScaling); + + mPointerVelocityControl.setCurve( + config.mousePointerAccelerationEnabled + ? createAccelerationCurveForPointerSensitivity(config.mousePointerSpeed) + : createFlatAccelerationCurve(config.mousePointerSpeed)); + + mWheelXVelocityControl.setParameters(config.wheelVelocityControlParameters); + mWheelYVelocityControl.setParameters(config.wheelVelocityControlParameters); } void CursorInputMapper::configureOnChangeDisplayInfo(const InputReaderConfiguration& config) { 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..8deff6b3aa 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -30,6 +30,7 @@ #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 +48,8 @@ namespace android { +namespace input_flags = com::android::input::flags; + // --- Constants --- // Artificial latency on synthetic events created from stylus data without corresponding touch @@ -299,6 +302,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 +352,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, @@ -1575,7 +1582,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 +1621,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 +1661,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 +1936,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 +1949,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 +2004,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 +2042,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 +2061,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 +2082,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 +2101,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 +2122,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 +2134,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 +2157,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 +2179,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 +2203,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 +2227,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 +2268,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 +2374,7 @@ void TouchInputMapper::cookPointerData() { pressure = in.pressure * mPressureScale; break; default: - pressure = in.isHovering ? 0 : 1; + pressure = isHovering ? 0 : 1; break; } @@ -2541,7 +2575,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 +2602,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 +2618,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 +2640,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 +2658,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 +2717,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 +3511,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 +3674,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 +3727,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 +3749,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 +4002,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..4ef0be8f8e 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; @@ -776,8 +779,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 +837,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 6bd949a09d..480e27604a 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> @@ -81,7 +85,6 @@ GestureConverter::GestureConverter(InputReaderContext& readerContext, const InputDeviceContext& deviceContext, int32_t deviceId) : mDeviceId(deviceId), mReaderContext(readerContext), - mEnableFlingStop(input_flags::enable_touchpad_fling_stop()), mEnableNoFocusChange(input_flags::enable_touchpad_no_focus_change()), // We can safely assume that ABS_MT_POSITION_X and _Y axes will be available, as EventHub // won't classify a device as a touchpad if they're not present. @@ -251,6 +254,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); @@ -313,6 +328,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, @@ -363,7 +387,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(); @@ -406,7 +430,7 @@ std::list<NotifyArgs> GestureConverter::handleFling(nsecs_t when, nsecs_t readTi break; case GESTURES_FLING_TAP_DOWN: if (mCurrentClassification == MotionClassification::NONE) { - if (mEnableFlingStop && mFlingMayBeInProgress) { + if (mFlingMayBeInProgress) { // The user has just touched the pad again after ending a two-finger scroll // motion, which might have started a fling. We want to stop the fling, but // unfortunately there's currently no API for doing so. Instead, send and @@ -422,7 +446,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)); @@ -480,7 +504,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; @@ -568,9 +592,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; @@ -645,6 +667,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 8d92ead80b..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, @@ -104,11 +106,10 @@ private: const int32_t mDeviceId; InputReaderContext& mReaderContext; - const bool mEnableFlingStop; 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..18d47f648b 100644 --- a/services/inputflinger/tests/Android.bp +++ b/services/inputflinger/tests/Android.bp @@ -40,14 +40,15 @@ 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", @@ -62,16 +63,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 +85,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 +110,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 +129,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/CursorInputMapper_test.cpp b/services/inputflinger/tests/CursorInputMapper_test.cpp index d4e8fdfdc5..594ee3b579 100644 --- a/services/inputflinger/tests/CursorInputMapper_test.cpp +++ b/services/inputflinger/tests/CursorInputMapper_test.cpp @@ -27,6 +27,7 @@ #include <com_android_input_flags.h> #include <gmock/gmock.h> #include <gtest/gtest.h> +#include <input/AccelerationCurve.h> #include <input/DisplayViewport.h> #include <input/InputEventLabels.h> #include <linux/input-event-codes.h> @@ -140,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, @@ -1028,6 +1029,34 @@ TEST_F(CursorInputMapperUnitTest, ConfigureDisplayIdNoAssociatedViewport) { WithCoords(0.0f, 0.0f))))); } +TEST_F(CursorInputMapperUnitTest, PointerAccelerationDisabled) { + mReaderConfiguration.mousePointerAccelerationEnabled = false; + mReaderConfiguration.mousePointerSpeed = 3; + mPropertyMap.addProperty("cursor.mode", "pointer"); + createMapper(); + + std::list<NotifyArgs> reconfigureArgs; + + reconfigureArgs += mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, + InputReaderConfiguration::Change::POINTER_SPEED); + + std::vector<AccelerationCurveSegment> curve = + createFlatAccelerationCurve(mReaderConfiguration.mousePointerSpeed); + double baseGain = curve[0].baseGain; + + std::list<NotifyArgs> motionArgs; + motionArgs += process(ARBITRARY_TIME, EV_REL, REL_X, 10); + motionArgs += process(ARBITRARY_TIME, EV_REL, REL_Y, 20); + motionArgs += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); + + const float expectedRelX = 10 * baseGain; + const float expectedRelY = 20 * baseGain; + ASSERT_THAT(motionArgs, + ElementsAre(VariantWith<NotifyMotionArgs>( + AllOf(WithMotionAction(HOVER_MOVE), + WithRelativeMotion(expectedRelX, expectedRelY))))); +} + TEST_F(CursorInputMapperUnitTest, ConfigureAccelerationWithAssociatedViewport) { mPropertyMap.addProperty("cursor.mode", "pointer"); DisplayViewport primaryViewport = createPrimaryViewport(ui::Rotation::Rotation0); @@ -1049,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(); @@ -1068,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)); @@ -1113,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/FakeInputDispatcherPolicy.cpp b/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp index db68d8a14a..c4257a83c3 100644 --- a/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp +++ b/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp @@ -16,6 +16,8 @@ #include "FakeInputDispatcherPolicy.h" +#include <variant> + #include <gtest/gtest.h> namespace android { @@ -409,12 +411,18 @@ void FakeInputDispatcherPolicy::interceptKeyBeforeQueueing(const KeyEvent& input void FakeInputDispatcherPolicy::interceptMotionBeforeQueueing(ui::LogicalDisplayId, uint32_t, int32_t, nsecs_t, uint32_t&) {} -nsecs_t FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&, - const KeyEvent&, uint32_t) { +std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> +FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, + uint32_t) { if (mConsumeKeyBeforeDispatching) { - return -1; + return inputdispatcher::KeyEntry::InterceptKeyResult::SKIP; } + nsecs_t delay = std::chrono::nanoseconds(mInterceptKeyTimeout).count(); + if (delay == 0) { + return inputdispatcher::KeyEntry::InterceptKeyResult::CONTINUE; + } + // Clear intercept state so we could dispatch the event in next wake. mInterceptKeyTimeout = 0ms; return delay; diff --git a/services/inputflinger/tests/FakeInputDispatcherPolicy.h b/services/inputflinger/tests/FakeInputDispatcherPolicy.h index a9e39d1630..c387eacb51 100644 --- a/services/inputflinger/tests/FakeInputDispatcherPolicy.h +++ b/services/inputflinger/tests/FakeInputDispatcherPolicy.h @@ -28,11 +28,13 @@ #include <optional> #include <queue> #include <string> +#include <variant> #include <vector> #include <android-base/logging.h> #include <android-base/thread_annotations.h> #include <binder/IBinder.h> +#include <dispatcher/Entry.h> #include <gui/PidUid.h> #include <gui/WindowInfo.h> #include <input/BlockingQueue.h> @@ -189,7 +191,8 @@ private: void interceptKeyBeforeQueueing(const KeyEvent& inputEvent, uint32_t&) override; void interceptMotionBeforeQueueing(ui::LogicalDisplayId, uint32_t, int32_t, nsecs_t, uint32_t&) override; - nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, uint32_t) override; + std::variant<nsecs_t, inputdispatcher::KeyEntry::InterceptKeyResult> + interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, uint32_t) override; std::optional<KeyEvent> dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent& event, uint32_t) override; void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask, 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 fe40a5eb4d..914f5abdbd 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" @@ -43,8 +47,12 @@ const auto TOUCHPAD_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 +63,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>(); @@ -1297,7 +1304,6 @@ TEST_F(GestureConverterTest, FlingTapDown) { TEST_F(GestureConverterTest, FlingTapDownAfterScrollStopsFling) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); - input_flags::enable_touchpad_fling_stop(true); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); converter.setDisplayId(ui::LogicalDisplayId::DEFAULT); @@ -1699,4 +1705,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 6eb1cd00d5..2b9b470a21 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> @@ -117,8 +118,12 @@ static constexpr gui::Uid SECONDARY_WINDOW_UID{1012}; // An arbitrary pid of the gesture monitor window static constexpr gui::Pid MONITOR_PID{2001}; +static constexpr int32_t FLAG_WINDOW_IS_OBSCURED = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED; +static constexpr int32_t FLAG_WINDOW_IS_PARTIALLY_OBSCURED = + AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED; + static constexpr int EXPECTED_WALLPAPER_FLAGS = - AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED; + FLAG_WINDOW_IS_OBSCURED | FLAG_WINDOW_IS_PARTIALLY_OBSCURED; using ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID; @@ -134,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 --- @@ -1211,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", @@ -4310,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); @@ -4340,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) @@ -4354,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(); @@ -4367,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); @@ -4395,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) @@ -4415,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) @@ -4634,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( @@ -4674,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( @@ -4721,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. @@ -4737,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", @@ -4786,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( @@ -4803,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) @@ -4822,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>(); @@ -5779,14 +5738,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}); @@ -5794,7 +5751,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) @@ -5803,45 +5763,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()); @@ -5852,8 +5799,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)); } /** @@ -5876,7 +5823,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", @@ -6010,7 +5956,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", @@ -6124,20 +6069,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", @@ -6161,14 +6104,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) @@ -6176,7 +6119,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) @@ -6555,19 +6499,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) { @@ -7003,7 +6975,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}; @@ -7012,11 +6984,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( @@ -8888,12 +8858,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); @@ -8911,13 +8879,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>(); @@ -9937,6 +9905,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); @@ -9947,6 +9924,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); @@ -9964,18 +9944,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( @@ -9985,55 +9970,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(); @@ -10043,21 +10028,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( @@ -10067,11 +10052,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(); } @@ -12389,6 +12374,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; @@ -12409,85 +12399,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) { @@ -12654,6 +12700,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)) @@ -12718,9 +12774,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})) @@ -12898,6 +12951,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) @@ -13620,14 +13685,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)); @@ -14753,4 +14814,636 @@ TEST_F(InputDispatcherTest, FocusedDisplayChangeIsNotified) { mFakePolicy->assertFocusedDisplayNotified(SECOND_DISPLAY_ID); } +class InputDispatcherObscuredFlagTest : public InputDispatcherTest { +protected: + std::shared_ptr<FakeApplicationHandle> mApplication; + std::shared_ptr<FakeApplicationHandle> mOcclusionApplication; + sp<FakeWindowHandle> mWindow; + sp<FakeWindowHandle> mOcclusionWindow; + + void SetUp() override { + InputDispatcherTest::SetUp(); + mDispatcher->setMaximumObscuringOpacityForTouch(0.8f); + mApplication = std::make_shared<FakeApplicationHandle>(); + mOcclusionApplication = std::make_shared<FakeApplicationHandle>(); + mWindow = sp<FakeWindowHandle>::make(mApplication, mDispatcher, "Window", DISPLAY_ID); + mWindow->setOwnerInfo(WINDOW_PID, WINDOW_UID); + + mOcclusionWindow = sp<FakeWindowHandle>::make(mOcclusionApplication, mDispatcher, + "Occlusion Window", DISPLAY_ID); + + mOcclusionWindow->setTouchable(false); + mOcclusionWindow->setTouchOcclusionMode(TouchOcclusionMode::USE_OPACITY); + mOcclusionWindow->setAlpha(0.7f); + mOcclusionWindow->setOwnerInfo(SECONDARY_WINDOW_PID, SECONDARY_WINDOW_UID); + } +}; + +/** + * Two windows. An untouchable window partially occludes a touchable region below it. + * Use a finger to touch the bottom window. + * When the finger touches down in the obscured area, the motion event should always have the + * FLAG_WINDOW_IS_OBSCURED flag, regardless of where it is moved to. If it starts from a + * non-obscured area, the motion event should always with a FLAG_WINDOW_IS_PARTIALLY_OBSCURED flag, + * regardless of where it is moved to. + */ +TEST_F(InputDispatcherObscuredFlagTest, TouchObscuredTest) { + mWindow->setFrame({0, 0, 100, 100}); + mOcclusionWindow->setFrame({0, 0, 100, 50}); + + mDispatcher->onWindowInfosChanged( + {{*mOcclusionWindow->getInfo(), *mWindow->getInfo()}, {}, 0, 0}); + + // If the finger touch goes down in the region that is obscured. + // Expect the entire stream to use FLAG_WINDOW_IS_OBSCURED. + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(10)) + .build()); + + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), + WithFlags(FLAG_WINDOW_IS_OBSCURED), + WithDisplayId(DISPLAY_ID))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(60)) + .build()); + + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), + WithFlags(FLAG_WINDOW_IS_OBSCURED), + WithDisplayId(DISPLAY_ID))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(110)) + .build()); + + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), + WithFlags(FLAG_WINDOW_IS_OBSCURED), + WithDisplayId(DISPLAY_ID))); +} + +/** + * Two windows. An untouchable window partially occludes a touchable region below it. + * Use a finger to touch the bottom window. + * When the finger starts from a non-obscured area, the motion event should always have the + * FLAG_WINDOW_IS_PARTIALLY_OBSCURED flag, regardless of where it is moved to. + */ +TEST_F(InputDispatcherObscuredFlagTest, TouchPartiallyObscuredTest) { + mWindow->setFrame({0, 0, 100, 100}); + mOcclusionWindow->setFrame({0, 0, 100, 50}); + + mDispatcher->onWindowInfosChanged( + {{*mOcclusionWindow->getInfo(), *mWindow->getInfo()}, {}, 0, 0}); + + // If the finger touch goes down in the region that is not directly obscured by the overlay. + // Expect the entire stream to use FLAG_WINDOW_IS_PARTIALLY_OBSCURED. + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(60)) + .build()); + + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), + WithFlags(FLAG_WINDOW_IS_PARTIALLY_OBSCURED), + WithDisplayId(DISPLAY_ID))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(80)) + .build()); + + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_MOVE), + WithFlags(FLAG_WINDOW_IS_PARTIALLY_OBSCURED), + WithDisplayId(DISPLAY_ID))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN) + .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(110)) + .build()); + + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), + WithFlags(FLAG_WINDOW_IS_PARTIALLY_OBSCURED), + WithDisplayId(DISPLAY_ID))); +} + +/** + * Two windows. An untouchable window partially occludes a touchable region below it. + * Use the mouse to hover over the bottom window. + * When the hover happens over the occluded area, the window below should receive a motion + * event with the FLAG_WINDOW_IS_OBSCURED flag. When the hover event moves to the non-occluded area, + * the window below should receive a motion event with the FLAG_WINDOW_IS_PARTIALLY_OBSCURED flag. + */ +TEST_F(InputDispatcherObscuredFlagTest, MouseHoverObscuredTest) { + mWindow->setFrame({0, 0, 100, 100}); + mOcclusionWindow->setFrame({0, 0, 100, 40}); + + mDispatcher->onWindowInfosChanged( + {{*mOcclusionWindow->getInfo(), *mWindow->getInfo()}, {}, 0, 0}); + + // TODO(b/328160937): The window should receive a motion event with the FLAG_WINDOW_IS_OBSCURED + // flag. + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/0, ToolType::MOUSE).x(50).y(20)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_ENTER), WithFlags(0))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/0, ToolType::MOUSE).x(50).y(30)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithFlags(0))); + + // TODO(b/328160937): The window should receive a motion event with the + // FLAG_WINDOW_IS_PARTIALLY_OBSCURED flag. + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/0, ToolType::MOUSE).x(50).y(50)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithFlags(0))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/0, ToolType::MOUSE).x(50).y(60)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithFlags(0))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/0, ToolType::MOUSE).x(50).y(110)) + .build()); + + // TODO(b/328160937): The window should receive a HOVER_EXIT with the + // FLAG_WINDOW_IS_PARTIALLY_OBSCURED flag. The cause of the current issue is that we moved the + // mouse to a location where there are no windows, so the HOVER_EXIT event cannot be generated. + mWindow->assertNoEvents(); +} + +/** + * Two windows. An untouchable window partially occludes a touchable region below it. + * Use the stylus to hover over the bottom window. + * When the hover happens over the occluded area, the window below should receive a motion + * event with the FLAG_WINDOW_IS_OBSCURED flag. When the hover event moves to the non-occluded area, + * the window below should receive a motion event with the FLAG_WINDOW_IS_PARTIALLY_OBSCURED flag. + */ +TEST_F(InputDispatcherObscuredFlagTest, StylusHoverObscuredTest) { + mWindow->setFrame({0, 0, 100, 100}); + mOcclusionWindow->setFrame({0, 0, 100, 40}); + + mDispatcher->onWindowInfosChanged( + {{*mOcclusionWindow->getInfo(), *mWindow->getInfo()}, {}, 0, 0}); + + // TODO(b/328160937): The window should receive a motion event with the FLAG_WINDOW_IS_OBSCURED + // flag. + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS) + .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS).x(50).y(20)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_ENTER), WithFlags(0))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS) + .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS).x(50).y(30)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithFlags(0))); + + // TODO(b/328160937): The window should receive a motion event with the + // FLAG_WINDOW_IS_PARTIALLY_OBSCURED flag. + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS) + .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS).x(50).y(50)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithFlags(0))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS) + .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS).x(50).y(60)) + .build()); + mWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithFlags(0))); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_EXIT, AINPUT_SOURCE_STYLUS) + .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS).x(50).y(70)) + .build()); + 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 9d2256f52f..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()); @@ -2474,10 +2537,10 @@ TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) { const auto syncTime = std::chrono::system_clock::now(); // After 72 ms, the event *will* be generated. If we wait the full 72 ms to check that NO event // is generated in that period, there will be a race condition between the event being generated - // and the test's wait timeout expiring. Thus, we wait for a shorter duration in the test, which - // will reduce the liklihood of the race condition occurring. - const auto waitUntilTimeForNoEvent = - syncTime + std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT / 2)); + // and the test's wait timeout expiring. Thus, we wait for a shorter duration in the test to + // ensure the event is not immediately generated, which should reduce the liklihood of the race + // condition occurring. + const auto waitUntilTimeForNoEvent = syncTime + std::chrono::milliseconds(1); mDevice->sendSync(); ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled(waitUntilTimeForNoEvent)); @@ -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..06d60ce53a 100644 --- a/services/inputflinger/tests/InterfaceMocks.h +++ b/services/inputflinger/tests/InterfaceMocks.h @@ -68,7 +68,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 +191,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 +269,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..17acdd49cf 100644 --- a/services/inputflinger/tests/KeyboardInputMapper_test.cpp +++ b/services/inputflinger/tests/KeyboardInputMapper_test.cpp @@ -1085,10 +1085,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 +1101,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, 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 27da3d33f9..38d0679095 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; @@ -140,6 +145,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 +313,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 +330,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 +341,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 +350,7 @@ TEST_F(PointerChoreographerTest, } TEST_F(PointerChoreographerTest, CallsNotifyPointerDisplayIdChanged) { - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, @@ -341,7 +362,7 @@ TEST_F(PointerChoreographerTest, CallsNotifyPointerDisplayIdChanged) { } TEST_F(PointerChoreographerTest, WhenViewportIsSetLaterCallsNotifyPointerDisplayIdChanged) { - mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + setDefaultMouseDisplayId(DISPLAY_ID); mChoreographer.notifyInputDevicesChanged( {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, @@ -354,7 +375,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 +394,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 +403,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 +412,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 +442,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 +478,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 +517,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 +564,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 +583,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 +620,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 +649,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 +662,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 +681,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 +1029,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 +1427,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 +1443,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 +1452,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 +1460,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 +1472,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 +1485,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 +1505,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 +1515,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 +1524,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 +1554,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 +1631,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 +1672,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 +1709,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 +1729,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 +1745,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 +1762,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 +1779,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 +1803,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 +1825,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*/>; @@ -2127,7 +2259,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 +2294,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 +2348,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 +2365,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 +2414,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 +2441,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 +2489,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 +2733,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 +2763,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,46 +2775,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), }; - std::unordered_map<ui::LogicalDisplayId, std::vector<PointerChoreographer::AdjacentDisplay>> - mTopology{ - {DISPLAY_CENTER_ID, - {{DISPLAY_TOP_ID, PointerChoreographer::DisplayPosition::TOP, 10.0f}, - {DISPLAY_RIGHT_ID, PointerChoreographer::DisplayPosition::RIGHT, 10.0f}, - {DISPLAY_BOTTOM_ID, PointerChoreographer::DisplayPosition::BOTTOM, 10.0f}, - {DISPLAY_LEFT_ID, PointerChoreographer::DisplayPosition::LEFT, 10.0f}, - {DISPLAY_TOP_RIGHT_CORNER_ID, PointerChoreographer::DisplayPosition::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); @@ -2702,71 +2846,315 @@ 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("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 {}; 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 7078e49343..1262af7bf9 100644 --- a/services/inputflinger/tests/TestEventMatchers.h +++ b/services/inputflinger/tests/TestEventMatchers.h @@ -38,10 +38,23 @@ struct PointF { auto operator<=>(const PointF&) const = default; }; +namespace internal { + +template <typename T> +static bool valuesMatch(T value1, T value2) { + if constexpr (std::is_floating_point_v<T>) { + return std::abs(value1 - value2) < EPSILON; + } else { + return value1 == value2; + } +} + inline std::string pointFToString(const PointF& p) { return std::string("(") + std::to_string(p.x) + ", " + std::to_string(p.y) + ")"; } +} // namespace internal + /// Source class WithSourceMatcher { public: @@ -440,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; @@ -456,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"; } @@ -492,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; @@ -506,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"; } @@ -706,8 +725,9 @@ public: } const PointerCoords& coords = event.pointerCoords[mPointerIndex]; - bool matches = mRelX == coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X) && - 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..bba7389eed 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; @@ -346,7 +374,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 +395,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/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..452b42826c 100644 --- a/services/sensorservice/senserservice_flags.aconfig +++ b/services/sensorservice/sensorservice_flags.aconfig @@ -28,3 +28,13 @@ 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 + } +}
\ No newline at end of file diff --git a/services/surfaceflinger/ActivePictureUpdater.cpp b/services/surfaceflinger/ActivePictureTracker.cpp index 210e948a49..4e6fa66ed8 100644 --- a/services/surfaceflinger/ActivePictureUpdater.cpp +++ b/services/surfaceflinger/ActivePictureTracker.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "ActivePictureUpdater.h" +#include "ActivePictureTracker.h" #include <algorithm> @@ -23,7 +23,10 @@ namespace android { -void ActivePictureUpdater::onLayerComposed(const Layer& layer, const LayerFE& layerFE, +using gui::ActivePicture; +using gui::IActivePictureListener; + +void ActivePictureTracker::onLayerComposed(const Layer& layer, const LayerFE& layerFE, const CompositionResult& result) { if (result.wasPictureProfileCommitted) { gui::ActivePicture picture; @@ -39,10 +42,47 @@ void ActivePictureUpdater::onLayerComposed(const Layer& layer, const LayerFE& la } } -bool ActivePictureUpdater::updateAndHasChanged() { +void ActivePictureTracker::updateAndNotifyListeners(const Listeners& listenersToAdd, + const Listeners& listenersToRemove) { + Listeners newListeners = updateListeners(listenersToAdd, listenersToRemove); + if (updateAndHasChanged()) { + for (auto listener : mListeners) { + listener->onActivePicturesChanged(getActivePictures()); + } + } else { + for (auto listener : newListeners) { + listener->onActivePicturesChanged(getActivePictures()); + } + } +} + +ActivePictureTracker::Listeners ActivePictureTracker::updateListeners( + const Listeners& listenersToAdd, const Listeners& listenersToRemove) { + Listeners newListeners; + for (auto listener : listenersToRemove) { + std::erase_if(mListeners, [listener](const sp<IActivePictureListener>& otherListener) { + return IInterface::asBinder(listener) == IInterface::asBinder(otherListener); + }); + } + for (auto listener : listenersToAdd) { + if (std::find_if(mListeners.begin(), mListeners.end(), + [listener](const sp<IActivePictureListener>& otherListener) { + return IInterface::asBinder(listener) == + IInterface::asBinder(otherListener); + }) == mListeners.end()) { + newListeners.push_back(listener); + } + } + for (auto listener : newListeners) { + mListeners.push_back(listener); + } + return newListeners; +} + +bool ActivePictureTracker::updateAndHasChanged() { bool hasChanged = true; if (mNewActivePictures.size() == mOldActivePictures.size()) { - auto compare = [](const gui::ActivePicture& lhs, const gui::ActivePicture& rhs) -> int { + auto compare = [](const ActivePicture& lhs, const ActivePicture& rhs) -> int { if (lhs.layerId == rhs.layerId) { return lhs.pictureProfileId < rhs.pictureProfileId; } @@ -59,7 +99,7 @@ bool ActivePictureUpdater::updateAndHasChanged() { return hasChanged; } -const std::vector<gui::ActivePicture>& ActivePictureUpdater::getActivePictures() const { +const std::vector<ActivePicture>& ActivePictureTracker::getActivePictures() const { return mOldActivePictures; } diff --git a/services/surfaceflinger/ActivePictureUpdater.h b/services/surfaceflinger/ActivePictureTracker.h index 20779bb0ff..cb319a58be 100644 --- a/services/surfaceflinger/ActivePictureUpdater.h +++ b/services/surfaceflinger/ActivePictureTracker.h @@ -19,6 +19,7 @@ #include <vector> #include <android/gui/ActivePicture.h> +#include <android/gui/IActivePictureListener.h> namespace android { @@ -27,21 +28,28 @@ class LayerFE; struct CompositionResult; // Keeps track of active pictures - layers that are undergoing picture processing. -class ActivePictureUpdater { +class ActivePictureTracker { public: + typedef std::vector<sp<gui::IActivePictureListener>> Listeners; + // Called for each visible layer when SurfaceFlinger finishes composing. void onLayerComposed(const Layer& layer, const LayerFE& layerFE, const CompositionResult& result); // Update internals and return whether the set of active pictures have changed. - bool updateAndHasChanged(); + void updateAndNotifyListeners(const Listeners& activePictureListenersToAdd, + const Listeners& activePictureListenersToRemove); // The current set of active pictures. const std::vector<gui::ActivePicture>& getActivePictures() const; private: + Listeners updateListeners(const Listeners& listenersToAdd, const Listeners& listenersToRemove); + bool updateAndHasChanged(); + std::vector<gui::ActivePicture> mOldActivePictures; std::vector<gui::ActivePicture> mNewActivePictures; + Listeners mListeners; }; } // namespace android diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 3f3d2c6cc6..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", ], } @@ -42,58 +42,57 @@ cc_defaults { name: "libsurfaceflinger_defaults", defaults: [ "android.hardware.graphics.composer3-ndk_shared", - "android.hardware.power-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", "libnativewindow", - "libpowermanager", "libprocessgroup", "libprotobuf-cpp-lite", "libstatslog_surfaceflinger", "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", ], } @@ -199,45 +198,42 @@ filegroup { name: "libsurfaceflinger_sources", srcs: [ ":libsurfaceflinger_backend_sources", - "ActivePictureUpdater.cpp", + "ActivePictureTracker.cpp", "BackgroundExecutor.cpp", "Client.cpp", "ClientCache.cpp", "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 77bf1457c3..6088e255df 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -110,8 +110,8 @@ binder::Status Client::mirrorDisplay(int64_t displayId, gui::CreateSurfaceResult 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/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp index 82eafd4fa8..2d0f874ad0 100644 --- a/services/surfaceflinger/CompositionEngine/Android.bp +++ b/services/surfaceflinger/CompositionEngine/Android.bp @@ -13,11 +13,11 @@ cc_defaults { defaults: [ "aconfig_lib_cc_static_link.defaults", "android.hardware.graphics.composer3-ndk_shared", - "android.hardware.power-ndk_shared", "librenderengine_deps", "libtimestats_deps", "surfaceflinger_defaults", "libsurfaceflinger_proto_deps", + "poweradvisor_deps", ], cflags: [ "-DLOG_TAG=\"CompositionEngine\"", 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/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/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h index 2e7a7d9c5a..c0243b81db 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h @@ -118,7 +118,8 @@ public: // isPeekingThrough specifies whether this layer will be shown through a // hole punch in a layer above it. virtual void writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t z, - bool zIsOverridden, bool isPeekingThrough) = 0; + bool zIsOverridden, bool isPeekingThrough, + bool isLutSupported) = 0; // Updates the cursor position with the HWC virtual void writeCursorPositionToHWC() const = 0; @@ -144,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/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h index 712b55123f..dea329078e 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h @@ -58,7 +58,7 @@ public: const std::optional<std::vector<std::optional<LutProperties>>> properties = std::nullopt) override; void writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t z, bool zIsOverridden, - bool isPeekingThrough) override; + bool isPeekingThrough, bool hasLutsProperties) override; void writeCursorPositionToHWC() const override; HWC2::Layer* getHwcLayer() const override; @@ -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; @@ -104,7 +104,7 @@ private: void detectDisallowedCompositionTypeChange( aidl::android::hardware::graphics::composer3::Composition from, aidl::android::hardware::graphics::composer3::Composition to) const; - bool isClientCompositionForced(bool isPeekingThrough) const; + bool isClientCompositionForced(bool isPeekingThrough, bool isCached) const; void updateLuts(const LayerFECompositionState&, const std::optional<std::vector<std::optional<LutProperties>>>& properties); }; 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/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h index 9333ebb8cd..be36db6fd1 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h @@ -47,7 +47,7 @@ public: (bool, bool, ui::Transform::RotationFlags, (const std::optional<std::vector<std::optional< aidl::android::hardware::graphics::composer3::LutProperties>>>))); - MOCK_METHOD5(writeStateToHWC, void(bool, bool, uint32_t, bool, bool)); + MOCK_METHOD(void, writeStateToHWC, (bool, bool, uint32_t, bool, bool, bool)); MOCK_CONST_METHOD0(writeCursorPositionToHWC, void()); MOCK_CONST_METHOD0(getHwcLayer, HWC2::Layer*()); @@ -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/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp index cfcce473a2..989f8e3c5e 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 { diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp index e37ce0a0eb..8364f4efa0 100644 --- a/services/surfaceflinger/CompositionEngine/src/Display.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp @@ -373,7 +373,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); } } diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index f9ed92d1ee..de1d13a8d1 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -810,7 +810,7 @@ void Output::commitPictureProfilesToCompositionState() { } auto compare = [](const ::android::compositionengine::OutputLayer* lhs, const ::android::compositionengine::OutputLayer* rhs) { - return lhs->getPictureProfilePriority() > rhs->getPictureProfilePriority(); + return lhs->getPictureProfilePriority() < rhs->getPictureProfilePriority(); }; std::priority_queue<::android::compositionengine::OutputLayer*, std::vector<::android::compositionengine::OutputLayer*>, decltype(compare)> @@ -909,6 +909,9 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr applyPictureProfile(); + auto* properties = getOverlaySupport(); + bool hasLutsProperties = properties && properties->lutProperties.has_value(); + compositionengine::OutputLayer* peekThroughLayer = nullptr; sp<GraphicBuffer> previousOverride = nullptr; bool includeGeometry = refreshArgs.updatingGeometryThisFrame; @@ -940,7 +943,7 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr includeGeometry = true; constexpr bool isPeekingThrough = true; peekThroughLayer->writeStateToHWC(includeGeometry, false, z++, overrideZ, - isPeekingThrough); + isPeekingThrough, hasLutsProperties); outputLayerHash ^= android::hashCombine( reinterpret_cast<uint64_t>(&peekThroughLayer->getLayerFE()), z, includeGeometry, overrideZ, isPeekingThrough, @@ -952,7 +955,8 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr } constexpr bool isPeekingThrough = false; - layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough); + layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough, + hasLutsProperties); if (!skipLayer) { outputLayerHash ^= android::hashCombine( reinterpret_cast<uint64_t>(&layer->getLayerFE()), @@ -1560,7 +1564,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)); diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp index a040c88e78..b1bbcac4bc 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); @@ -449,7 +460,8 @@ void OutputLayer::commitPictureProfileToCompositionState() { } void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t z, - bool zIsOverridden, bool isPeekingThrough) { + bool zIsOverridden, bool isPeekingThrough, + bool hasLutsProperties) { const auto& state = getState(); // Skip doing this if there is no HWC interface if (!state.hwc) { @@ -491,8 +503,9 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough, skipLayer); - - writeLutToHWC(hwcLayer.get(), *outputIndependentState); + if (hasLutsProperties) { + writeLutToHWC(hwcLayer.get(), *outputIndependentState); + } if (requestedCompositionType == Composition::SOLID_COLOR) { writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState); @@ -500,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, @@ -589,29 +611,30 @@ void OutputLayer::writeOutputIndependentGeometryStateToHWC( void OutputLayer::writeLutToHWC(HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState) { - if (!outputIndependentState.luts) { - return; - } - auto& lutFileDescriptor = outputIndependentState.luts->getLutFileDescriptor(); - auto lutOffsets = outputIndependentState.luts->offsets; - auto& lutProperties = outputIndependentState.luts->lutProperties; + Luts luts; + // if outputIndependentState.luts is nullptr, it means we want to clear the LUTs + // and we pass an empty Luts object to the HWC. + if (outputIndependentState.luts) { + auto& lutFileDescriptor = outputIndependentState.luts->getLutFileDescriptor(); + auto lutOffsets = outputIndependentState.luts->offsets; + auto& lutProperties = outputIndependentState.luts->lutProperties; + + std::vector<LutProperties> aidlProperties; + aidlProperties.reserve(lutProperties.size()); + for (size_t i = 0; i < lutOffsets.size(); i++) { + aidlProperties.emplace_back( + LutProperties{.dimension = static_cast<LutProperties::Dimension>( + lutProperties[i].dimension), + .size = lutProperties[i].size, + .samplingKeys = {static_cast<LutProperties::SamplingKey>( + lutProperties[i].samplingKey)}}); + } - std::vector<LutProperties> aidlProperties; - aidlProperties.reserve(lutProperties.size()); - for (size_t i = 0; i < lutOffsets.size(); i++) { - LutProperties properties; - properties.dimension = static_cast<LutProperties::Dimension>(lutProperties[i].dimension); - properties.size = lutProperties[i].size; - properties.samplingKeys = { - static_cast<LutProperties::SamplingKey>(lutProperties[i].samplingKey)}; - aidlProperties.emplace_back(properties); + luts.pfd.set(dup(lutFileDescriptor.get())); + luts.offsets = lutOffsets; + luts.lutProperties = std::move(aidlProperties); } - Luts luts; - luts.pfd = ndk::ScopedFileDescriptor(dup(lutFileDescriptor.get())); - luts.offsets = lutOffsets; - luts.lutProperties = std::move(aidlProperties); - switch (auto error = hwcLayer->setLuts(luts)) { case hal::Error::NONE: break; @@ -853,7 +876,8 @@ void OutputLayer::writeCompositionTypeToHWC(HWC2::Layer* hwcLayer, bool isPeekingThrough, bool skipLayer) { auto& outputDependentState = editState(); - if (isClientCompositionForced(isPeekingThrough)) { + bool isCached = !skipLayer && outputDependentState.overrideInfo.buffer; + if (isClientCompositionForced(isPeekingThrough, isCached)) { // If we are forcing client composition, we need to tell the HWC requestedCompositionType = Composition::CLIENT; } @@ -943,9 +967,12 @@ void OutputLayer::detectDisallowedCompositionTypeChange(Composition from, Compos } } -bool OutputLayer::isClientCompositionForced(bool isPeekingThrough) const { +bool OutputLayer::isClientCompositionForced(bool isPeekingThrough, bool isCached) const { + // If this layer was flattened into a CachedSet then it is not necessary for + // the GPU to compose it. + bool requiresClientDrawnRoundedCorners = !isCached && getLayerFE().hasRoundedCorners(); return getState().forceClientComposition || - (!isPeekingThrough && getLayerFE().hasRoundedCorners()); + (!isPeekingThrough && requiresClientDrawnRoundedCorners); } void OutputLayer::applyDeviceCompositionTypeChange(Composition compositionType) { @@ -961,6 +988,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() { @@ -983,7 +1017,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); @@ -1002,9 +1036,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/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp index 3e0c390a5d..ad65c4422e 100644 --- a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp @@ -61,7 +61,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()); } diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp index dbffe80a3a..ca262ee16a 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp @@ -541,6 +541,9 @@ struct OutputLayerPartialMockForUpdateCompositionState : public impl::OutputLaye MOCK_CONST_METHOD1(calculateOutputSourceCrop, FloatRect(uint32_t)); MOCK_CONST_METHOD0(calculateOutputDisplayFrame, Rect()); MOCK_CONST_METHOD1(calculateOutputRelativeBufferTransform, uint32_t(uint32_t)); + MOCK_METHOD(void, updateLuts, + (const LayerFECompositionState&, + const std::optional<std::vector<std::optional<LutProperties>>>&)); // compositionengine::OutputLayer overrides const compositionengine::Output& getOutput() const override { return mOutput; } @@ -985,21 +988,24 @@ TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoFECompositionState) { EXPECT_CALL(mLayerFE, getCompositionState()).WillOnce(Return(nullptr)); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCState) { mOutputLayer.editState().hwc.reset(); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCLayer) { mOutputLayer.editState().hwc = impl::OutputLayerCompositionState::Hwc(nullptr); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, canSetAllState) { @@ -1010,7 +1016,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, canSetAllState) { EXPECT_CALL(mLayerFE, hasRoundedCorners()).WillOnce(Return(false)); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerTest, displayInstallOrientationBufferTransformSetTo90) { @@ -1041,7 +1048,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSolidColor) { expectSetColorCall(); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSideband) { @@ -1052,7 +1060,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForSideband) { expectSetCompositionTypeCall(Composition::SIDEBAND); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForCursor) { @@ -1063,7 +1072,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForCursor) { expectSetCompositionTypeCall(Composition::CURSOR); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForDevice) { @@ -1074,7 +1084,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, canSetPerFrameStateForDevice) { expectSetCompositionTypeCall(Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsNotSetIfUnchanged) { @@ -1087,7 +1098,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsNotSetIfUnchanged) { expectNoSetCompositionTypeCall(); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfColorTransformNotSupported) { @@ -1098,7 +1110,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfColorTransf expectSetCompositionTypeCall(Composition::CLIENT); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfClientCompositionForced) { @@ -1111,7 +1124,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, compositionTypeIsSetToClientIfClientCompo expectSetCompositionTypeCall(Composition::CLIENT); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, allStateIncludesMetadataIfPresent) { @@ -1125,7 +1139,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, allStateIncludesMetadataIfPresent) { expectSetCompositionTypeCall(Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, perFrameStateDoesNotIncludeMetadataIfPresent) { @@ -1137,7 +1152,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, perFrameStateDoesNotIncludeMetadataIfPres expectSetCompositionTypeCall(Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, overriddenSkipLayerDoesNotSendBuffer) { @@ -1152,7 +1168,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, overriddenSkipLayerDoesNotSendBuffer) { expectSetCompositionTypeCall(Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, overriddenSkipLayerForSolidColorDoesNotSendBuffer) { @@ -1167,7 +1184,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, overriddenSkipLayerForSolidColorDoesNotSe expectSetCompositionTypeCall(Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) { @@ -1182,7 +1200,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) { expectSetCompositionTypeCall(Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoForSolidColorIfPresent) { @@ -1197,7 +1216,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoForSolidColorIfPresen expectSetCompositionTypeCall(Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, previousOverriddenLayerSendsSurfaceDamage) { @@ -1211,7 +1231,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, previousOverriddenLayerSendsSurfaceDamage expectSetCompositionTypeCall(Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, previousSkipLayerSendsUpdatedDeviceCompositionInfo) { @@ -1227,7 +1248,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, previousSkipLayerSendsUpdatedDeviceCompos expectSetCompositionTypeCall(Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, previousSkipLayerSendsUpdatedClientCompositionInfo) { @@ -1244,7 +1266,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, previousSkipLayerSendsUpdatedClientCompos expectSetCompositionTypeCall(Composition::CLIENT); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, peekThroughChangesBlendMode) { @@ -1258,7 +1281,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, peekThroughChangesBlendMode) { expectPerFrameCommonCalls(); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, isPeekingThroughSetsOverride) { @@ -1266,7 +1290,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, isPeekingThroughSetsOverride) { expectPerFrameCommonCalls(); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ true); + /*zIsOverridden*/ false, /*isPeekingThrough*/ true, + /*hasLutsProperties*/ false); EXPECT_TRUE(mOutputLayer.getState().hwc->stateOverridden); } @@ -1276,7 +1301,7 @@ TEST_F(OutputLayerWriteStateToHWCTest, zIsOverriddenSetsOverride) { mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, /*zIsOverridden*/ true, /*isPeekingThrough*/ - false); + false, /*hasLutsProperties*/ false); EXPECT_TRUE(mOutputLayer.getState().hwc->stateOverridden); } @@ -1288,7 +1313,7 @@ TEST_F(OutputLayerWriteStateToHWCTest, roundedCornersForceClientComposition) { mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, /*zIsOverridden*/ false, /*isPeekingThrough*/ - false); + false, /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, roundedCornersPeekingThroughAllowsDeviceComposition) { @@ -1301,7 +1326,7 @@ TEST_F(OutputLayerWriteStateToHWCTest, roundedCornersPeekingThroughAllowsDeviceC mLayerFEState.compositionType = Composition::DEVICE; mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, /*zIsOverridden*/ false, /*isPeekingThrough*/ - true); + true, /*hasLutsProperties*/ false); EXPECT_EQ(Composition::DEVICE, mOutputLayer.getState().hwc->hwcCompositionType); } @@ -1318,7 +1343,7 @@ TEST_F(OutputLayerWriteStateToHWCTest, setBlockingRegion) { mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, /*zIsOverridden*/ false, /*isPeekingThrough*/ - false); + false, /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, setCompositionTypeRefreshRateIndicator) { @@ -1330,7 +1355,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, setCompositionTypeRefreshRateIndicator) { expectSetCompositionTypeCall(Composition::REFRESH_RATE_INDICATOR); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, setsPictureProfileWhenCommitted) { @@ -1349,7 +1375,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, setsPictureProfileWhenCommitted) { mOutputLayer.commitPictureProfileToCompositionState(); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, doesNotSetPictureProfileWhenNotCommitted) { @@ -1367,7 +1394,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, doesNotSetPictureProfileWhenNotCommitted) EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(_)).Times(0); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } TEST_F(OutputLayerWriteStateToHWCTest, doesNotSetPictureProfileWhenNotCommittedLater) { @@ -1386,7 +1414,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, doesNotSetPictureProfileWhenNotCommittedL mOutputLayer.commitPictureProfileToCompositionState(); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); expectGeometryCommonCalls(); expectPerFrameCommonCalls(); @@ -1395,7 +1424,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, doesNotSetPictureProfileWhenNotCommittedL EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(PictureProfileHandle(1))).Times(0); // No committing of picture profile before writing the state mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); } /* @@ -1441,21 +1471,24 @@ TEST_F(OutputLayerUncacheBufferTest, canUncacheAndReuseSlot) { mLayerFEState.buffer = kBuffer1; EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 0, kBuffer1, kFence)); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); Mock::VerifyAndClearExpectations(&mHwcLayer); // Buffer2 is stored in slot 1 mLayerFEState.buffer = kBuffer2; EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 1, kBuffer2, kFence)); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); Mock::VerifyAndClearExpectations(&mHwcLayer); // Buffer3 is stored in slot 2 mLayerFEState.buffer = kBuffer3; EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 2, kBuffer3, kFence)); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); Mock::VerifyAndClearExpectations(&mHwcLayer); // Buffer2 becomes the active buffer again (with a nullptr) and reuses slot 1 @@ -1463,7 +1496,8 @@ TEST_F(OutputLayerUncacheBufferTest, canUncacheAndReuseSlot) { sp<GraphicBuffer> nullBuffer = nullptr; EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 1, nullBuffer, kFence)); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); Mock::VerifyAndClearExpectations(&mHwcLayer); // Buffer slots are cleared @@ -1481,7 +1515,8 @@ TEST_F(OutputLayerUncacheBufferTest, canUncacheAndReuseSlot) { mLayerFEState.buffer = kBuffer1; EXPECT_CALL(mHwcLayer, setBuffer(/*slot*/ 1, kBuffer1, kFence)); mOutputLayer.writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false); Mock::VerifyAndClearExpectations(&mHwcLayer); } diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index 442b603ca0..09ad9fa497 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -813,19 +813,22 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers updateCompositionState(false, false, ui::Transform::ROT_180, _)); EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180, _)); EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180, _)); EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); injectOutputLayer(layer1); @@ -852,17 +855,20 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentF EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); injectOutputLayer(layer1); @@ -888,17 +894,20 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLa EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); injectOutputLayer(layer1); @@ -932,7 +941,8 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) { uint32_t z = 0; EXPECT_CALL(*layer0.outputLayer, writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer0.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); // After calling planComposition (which clears overrideInfo), this test sets @@ -942,15 +952,17 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) { EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++, /*zIsOverridden*/ true, /*isPeekingThrough*/ - true)); + true, /*hasLutsProperties*/ false)); EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++, - /*zIsOverridden*/ true, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ true, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++, - /*zIsOverridden*/ true, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ true, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); injectOutputLayer(layer0); @@ -4962,12 +4974,14 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) { EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); layer2.layerFEState.backgroundBlurRadius = 10; @@ -4996,17 +5010,20 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); layer2.layerFEState.backgroundBlurRadius = 10; @@ -5036,17 +5053,20 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) { EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0, _)); EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++, - /*zIsOverridden*/ false, /*isPeekingThrough*/ false)); + /*zIsOverridden*/ false, /*isPeekingThrough*/ false, + /*hasLutsProperties*/ false)); EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); BlurRegion region; @@ -5080,14 +5100,14 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, assignsDisplayProfileBasedOnLay InjectedLayer layer1; injectOutputLayer(layer1); PictureProfileHandle profileForLayer1(1); - EXPECT_CALL(*layer1.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(3)); + EXPECT_CALL(*layer1.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(1)); EXPECT_CALL(*layer1.outputLayer, getPictureProfileHandle()) .WillRepeatedly(ReturnRef(profileForLayer1)); InjectedLayer layer2; injectOutputLayer(layer2); PictureProfileHandle profileForLayer2(2); - EXPECT_CALL(*layer2.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(1)); + EXPECT_CALL(*layer2.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(3)); EXPECT_CALL(*layer2.outputLayer, getPictureProfileHandle()) .WillRepeatedly(ReturnRef(profileForLayer2)); @@ -5101,13 +5121,13 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, assignsDisplayProfileBasedOnLay // Because StrictMock EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer1.outputLayer, updateCompositionState(_, _, _, _)); - EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(_, _, _, _, _)); + EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(_, _, _, _, _, _)); EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer2.outputLayer, updateCompositionState(_, _, _, _)); - EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(_, _, _, _, _)); + EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(_, _, _, _, _, _)); EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer3.outputLayer, updateCompositionState(_, _, _, _)); - EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(_, _, _, _, _)); + EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(_, _, _, _, _, _)); // No layer picture profiles should be committed EXPECT_CALL(*layer1.outputLayer, commitPictureProfileToCompositionState).Times(0); @@ -5143,14 +5163,14 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, assignsLayerProfileBasedOnLayer InjectedLayer layer1; injectOutputLayer(layer1); PictureProfileHandle profileForLayer1(1); - EXPECT_CALL(*layer1.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(3)); + EXPECT_CALL(*layer1.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(1)); EXPECT_CALL(*layer1.outputLayer, getPictureProfileHandle()) .WillRepeatedly(ReturnRef(profileForLayer1)); InjectedLayer layer2; injectOutputLayer(layer2); PictureProfileHandle profileForLayer2(2); - EXPECT_CALL(*layer2.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(1)); + EXPECT_CALL(*layer2.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(3)); EXPECT_CALL(*layer2.outputLayer, getPictureProfileHandle()) .WillRepeatedly(ReturnRef(profileForLayer2)); @@ -5164,13 +5184,13 @@ TEST_F(OutputUpdateAndWriteCompositionStateTest, assignsLayerProfileBasedOnLayer // Because StrictMock EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer1.outputLayer, updateCompositionState(_, _, _, _)); - EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(_, _, _, _, _)); + EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(_, _, _, _, _, _)); EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer2.outputLayer, updateCompositionState(_, _, _, _)); - EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(_, _, _, _, _)); + EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(_, _, _, _, _, _)); EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer3.outputLayer, updateCompositionState(_, _, _, _)); - EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(_, _, _, _, _)); + EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(_, _, _, _, _, _)); // The two highest priority layers should have their picture profiles committed EXPECT_CALL(*layer1.outputLayer, commitPictureProfileToCompositionState).Times(0); 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/Display/DisplaySnapshot.cpp b/services/surfaceflinger/Display/DisplaySnapshot.cpp index 0c7a58ee71..39607400d6 100644 --- a/services/surfaceflinger/Display/DisplaySnapshot.cpp +++ b/services/surfaceflinger/Display/DisplaySnapshot.cpp @@ -26,11 +26,12 @@ namespace android::display { -DisplaySnapshot::DisplaySnapshot(PhysicalDisplayId displayId, +DisplaySnapshot::DisplaySnapshot(PhysicalDisplayId displayId, uint8_t port, ui::DisplayConnectionType connectionType, DisplayModes&& displayModes, ui::ColorModes&& colorModes, std::optional<DeviceProductInfo>&& deviceProductInfo) : mDisplayId(displayId), + mPort(port), mConnectionType(connectionType), mDisplayModes(std::move(displayModes)), mColorModes(std::move(colorModes)), @@ -62,6 +63,8 @@ ui::ColorModes DisplaySnapshot::filterColorModes(bool supportsWideColor) const { void DisplaySnapshot::dump(utils::Dumper& dumper) const { using namespace std::string_view_literals; + dumper.dump("port"sv, mPort); + dumper.dump("connectionType"sv, ftl::enum_string(mConnectionType)); dumper.dump("colorModes"sv); diff --git a/services/surfaceflinger/Display/DisplaySnapshot.h b/services/surfaceflinger/Display/DisplaySnapshot.h index 23471f5d8e..0030aad91e 100644 --- a/services/surfaceflinger/Display/DisplaySnapshot.h +++ b/services/surfaceflinger/Display/DisplaySnapshot.h @@ -16,6 +16,7 @@ #pragma once +#include <cstdint> #include <optional> #include <ui/ColorMode.h> @@ -30,13 +31,14 @@ namespace android::display { // Immutable state of a physical display, captured on hotplug. class DisplaySnapshot { public: - DisplaySnapshot(PhysicalDisplayId, ui::DisplayConnectionType, DisplayModes&&, ui::ColorModes&&, - std::optional<DeviceProductInfo>&&); + DisplaySnapshot(PhysicalDisplayId, uint8_t, ui::DisplayConnectionType, DisplayModes&&, + ui::ColorModes&&, std::optional<DeviceProductInfo>&&); DisplaySnapshot(const DisplaySnapshot&) = delete; DisplaySnapshot(DisplaySnapshot&&) = default; PhysicalDisplayId displayId() const { return mDisplayId; } + uint8_t port() const { return mPort; } ui::DisplayConnectionType connectionType() const { return mConnectionType; } std::optional<DisplayModeId> translateModeId(hal::HWConfigId) const; @@ -51,6 +53,7 @@ public: private: const PhysicalDisplayId mDisplayId; + const uint8_t mPort; const ui::DisplayConnectionType mConnectionType; // Effectively const except in move constructor. diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index c743ea2ff4..e8b09b043e 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -223,9 +223,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); diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index af2b48fc07..b5a543a7c1 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -98,7 +98,7 @@ public: 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); @@ -260,6 +260,7 @@ struct DisplayDeviceState { struct Physical { PhysicalDisplayId id; hardware::graphics::composer::hal::HWDisplayId hwcDisplayId; + uint8_t port; DisplayModePtr activeMode; bool operator==(const Physical& other) const { diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp index 25f6513ffa..bb6bebed8d 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); @@ -1678,6 +1720,29 @@ Error AidlComposer::setLayerPictureProfileId(Display display, Layer layer, Pictu return error; } +Error AidlComposer::getLuts(Display display, const std::vector<sp<GraphicBuffer>>& buffers, + std::vector<aidl::android::hardware::graphics::composer3::Luts>* luts) { + std::vector<aidl::android::hardware::graphics::composer3::Buffer> aidlBuffers; + aidlBuffers.reserve(buffers.size()); + + for (auto& buffer : buffers) { + if (buffer.get()) { + aidl::android::hardware::graphics::composer3::Buffer aidlBuffer; + aidlBuffer.handle.emplace(::android::dupToAidl(buffer->getNativeBuffer()->handle)); + aidlBuffers.emplace_back(std::move(aidlBuffer)); + } + } + + const auto status = + mAidlComposerClient->getLuts(translate<int64_t>(display), aidlBuffers, luts); + if (!status.isOk()) { + ALOGE("getLuts failed %s", status.getDescription().c_str()); + return static_cast<Error>(status.getServiceSpecificError()); + } + + return Error::NONE; +} + ftl::Optional<std::reference_wrapper<ComposerClientWriter>> AidlComposer::getWriter(Display display) REQUIRES_SHARED(mMutex) { return mWriters.get(display); diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h index 6b5ebc59a3..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; @@ -245,6 +250,8 @@ public: Error getMaxLayerPictureProfiles(Display, int32_t* outMaxProfiles) override; Error setDisplayPictureProfileId(Display, PictureProfileId id) override; Error setLayerPictureProfileId(Display, Layer, PictureProfileId id) override; + Error getLuts(Display, const std::vector<sp<GraphicBuffer>>&, + std::vector<aidl::android::hardware::graphics::composer3::Luts>*) override; private: // Many public functions above simply write a command into the command @@ -252,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 ff292fa350..018ee6e461 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -46,6 +46,7 @@ #include <aidl/android/hardware/graphics/composer3/DisplayConfiguration.h> #include <aidl/android/hardware/graphics/composer3/DisplayLuts.h> #include <aidl/android/hardware/graphics/composer3/IComposerCallback.h> +#include <aidl/android/hardware/graphics/composer3/Luts.h> #include <aidl/android/hardware/graphics/composer3/OverlayProperties.h> #include <optional> @@ -156,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; @@ -313,6 +318,8 @@ public: virtual Error getMaxLayerPictureProfiles(Display display, int32_t* outMaxProfiles) = 0; virtual Error setDisplayPictureProfileId(Display display, PictureProfileId id) = 0; virtual Error setLayerPictureProfileId(Display display, Layer layer, PictureProfileId id) = 0; + virtual Error getLuts(Display display, const std::vector<sp<GraphicBuffer>>&, + std::vector<V3_0::Luts>*) = 0; }; } // namespace Hwc2 diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index 081f4aa269..01f382f0e8 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -629,7 +629,7 @@ Error Display::getRequestedLuts(LayerLuts* outLuts, auto layer = getLayerById(layerIds[i]); if (layer) { auto& layerLut = tmpLuts[i]; - if (layerLut.luts.pfd.get() > 0 && layerLut.luts.offsets.has_value()) { + if (layerLut.luts.pfd.get() >= 0 && layerLut.luts.offsets.has_value()) { const auto& offsets = layerLut.luts.offsets.value(); std::vector<std::pair<int32_t, LutProperties>> lutOffsetsAndProperties; lutOffsetsAndProperties.reserve(offsets.size()); @@ -638,9 +638,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); } } @@ -669,6 +677,12 @@ Error Display::setPictureProfileHandle(const PictureProfileHandle& handle) { return static_cast<Error>(error); } +Error Display::getLuts(const std::vector<sp<GraphicBuffer>>& buffers, + std::vector<aidl::android::hardware::graphics::composer3::Luts>* outLuts) { + const auto error = mComposer.getLuts(mId, buffers, outLuts); + return static_cast<Error>(error); +} + // For use by Device void Display::setConnected(bool connected) { diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index 6740d8a832..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> @@ -203,6 +203,9 @@ public: [[nodiscard]] virtual hal::Error getMaxLayerPictureProfiles(int32_t* maxProfiles) = 0; [[nodiscard]] virtual hal::Error setPictureProfileHandle( const PictureProfileHandle& handle) = 0; + [[nodiscard]] virtual hal::Error getLuts( + const std::vector<android::sp<android::GraphicBuffer>>&, + std::vector<aidl::android::hardware::graphics::composer3::Luts>*) = 0; }; namespace impl { @@ -288,6 +291,8 @@ public: hal::Error setIdleTimerEnabled(std::chrono::milliseconds timeout) override; hal::Error getMaxLayerPictureProfiles(int32_t* maxProfiles) override; hal::Error setPictureProfileHandle(const android::PictureProfileHandle& handle) override; + hal::Error getLuts(const std::vector<android::sp<android::GraphicBuffer>>&, + std::vector<aidl::android::hardware::graphics::composer3::Luts>*) override; // Other Display methods hal::HWDisplayId getId() const override { return mId; } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 55ccdefa7a..545ed1949a 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -138,13 +138,13 @@ 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: + case HotplugEvent::LinkUnstable: return {}; } } @@ -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. @@ -1046,11 +1054,21 @@ status_t HWComposer::setDisplayPictureProfileHandle(PhysicalDisplayId displayId, return NO_ERROR; } +status_t HWComposer::getLuts( + PhysicalDisplayId displayId, const std::vector<sp<GraphicBuffer>>& buffers, + std::vector<aidl::android::hardware::graphics::composer3::Luts>* luts) { + RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); + auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; + auto error = hwcDisplay->getLuts(buffers, luts); + RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); + return NO_ERROR; +} + const std::unordered_map<std::string, bool>& HWComposer::getSupportedLayerGenericMetadata() const { return mSupportedLayerGenericMetadata; } -ftl::SmallMap<HWC2::Layer*, ndk::ScopedFileDescriptor, 20>& +ftl::SmallMap<HWC2::Layer*, ::android::base::unique_fd, 20>& HWComposer::getLutFileDescriptorMapper() { return mLutFileDescriptorMapper; } @@ -1113,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); @@ -1160,7 +1185,7 @@ std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect( mHasMultiDisplaySupport ? "generalized" : "legacy"); } - if (shouldIgnoreHotplugConnect(hwcDisplayId, hasDisplayIdentificationData)) { + if (shouldIgnoreHotplugConnect(hwcDisplayId, port, hasDisplayIdentificationData)) { return {}; } @@ -1180,6 +1205,7 @@ std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect( return DisplayIdentificationInfo{.id = PhysicalDisplayId::fromPort(port), .name = isPrimary ? "Primary display" : "Secondary display", + .port = port, .deviceProductInfo = std::nullopt}; }(); @@ -1191,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; } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 52662cffbb..2c0aa3d6d5 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> @@ -55,6 +56,7 @@ #include <aidl/android/hardware/graphics/composer3/DisplayCapability.h> #include <aidl/android/hardware/graphics/composer3/DisplayLuts.h> #include <aidl/android/hardware/graphics/composer3/LutProperties.h> +#include <aidl/android/hardware/graphics/composer3/Luts.h> #include <aidl/android/hardware/graphics/composer3/OutputType.h> #include <aidl/android/hardware/graphics/composer3/OverlayProperties.h> @@ -143,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 @@ -230,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 @@ -324,6 +327,8 @@ public: virtual int32_t getMaxLayerPictureProfiles(PhysicalDisplayId) = 0; virtual status_t setDisplayPictureProfileHandle(PhysicalDisplayId, const PictureProfileHandle& handle) = 0; + virtual status_t getLuts(PhysicalDisplayId, const std::vector<sp<GraphicBuffer>>&, + std::vector<aidl::android::hardware::graphics::composer3::Luts>*) = 0; }; static inline bool operator==(const android::HWComposer::DeviceRequestedChanges& lhs, @@ -358,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 @@ -432,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; @@ -491,6 +494,8 @@ public: int32_t getMaxLayerPictureProfiles(PhysicalDisplayId) override; status_t setDisplayPictureProfileHandle(PhysicalDisplayId, const android::PictureProfileHandle& profile) override; + status_t getLuts(PhysicalDisplayId, const std::vector<sp<GraphicBuffer>>&, + std::vector<aidl::android::hardware::graphics::composer3::Luts>*) override; // for debugging ---------------------------------------------------------- void dump(std::string& out) const override; @@ -521,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; @@ -538,7 +544,8 @@ private: std::optional<DisplayIdentificationInfo> onHotplugConnect(hal::HWDisplayId); std::optional<DisplayIdentificationInfo> onHotplugDisconnect(hal::HWDisplayId); - bool shouldIgnoreHotplugConnect(hal::HWDisplayId, bool hasDisplayIdentificationData) const; + 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; @@ -560,6 +567,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 5703a2d37c..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); @@ -1452,6 +1460,11 @@ Error HidlComposer::getMaxLayerPictureProfiles(Display, int32_t*) { return Error::UNSUPPORTED; } +Error HidlComposer::getLuts(Display, const std::vector<sp<GraphicBuffer>>&, + std::vector<aidl::android::hardware::graphics::composer3::Luts>*) { + return Error::UNSUPPORTED; +} + Error HidlComposer::setDisplayPictureProfileId(Display, PictureProfileId) { return Error::UNSUPPORTED; } diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h index 42ba9a957b..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; @@ -359,6 +363,8 @@ public: Error getMaxLayerPictureProfiles(Display, int32_t* outMaxProfiles) override; Error setDisplayPictureProfileId(Display, PictureProfileId) override; Error setLayerPictureProfileId(Display, Layer, PictureProfileId) override; + Error getLuts(Display, const std::vector<sp<GraphicBuffer>>&, + std::vector<aidl::android::hardware::graphics::composer3::Luts>*) override; private: class CommandWriter : public CommandWriterBase { 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/LayerLifecycleManager.cpp b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp index f1091a6f03..d369403737 100644 --- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp +++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp @@ -182,8 +182,8 @@ void LayerLifecycleManager::onHandlesDestroyed( } } -void LayerLifecycleManager::applyTransactions(const std::vector<TransactionState>& transactions, - bool ignoreUnknownLayers) { +void LayerLifecycleManager::applyTransactions( + const std::vector<QueuedTransactionState>& transactions, bool ignoreUnknownLayers) { for (const auto& transaction : transactions) { for (const auto& resolvedComposerState : transaction.states) { const auto& clientState = resolvedComposerState.state; diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h index 330da9a3d3..072be35b26 100644 --- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h +++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h @@ -16,8 +16,8 @@ #pragma once +#include "QueuedTransactionState.h" #include "RequestedLayerState.h" -#include "TransactionState.h" namespace android::surfaceflinger::frontend { @@ -43,7 +43,8 @@ public: // the layers it is unreachable. When using the LayerLifecycleManager for layer trace // generation we may encounter layers which are known because we don't have an explicit // lifecycle. Ignore these errors while we have to interop with legacy. - void applyTransactions(const std::vector<TransactionState>&, bool ignoreUnknownLayers = false); + void applyTransactions(const std::vector<QueuedTransactionState>&, + bool ignoreUnknownLayers = false); // Ignore unknown handles when iteroping with legacy front end. In the old world, we // would create child layers which are not necessary with the new front end. This means // we will get notified for handle changes that don't exist in the new front end. diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp index 58f6b96e57..1f0d5d05a9 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 { @@ -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()) { @@ -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; } @@ -418,7 +428,7 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate } if (forceUpdate || requested.what & layer_state_t::eAppContentPriorityChanged) { // TODO(b/337330263): Also consider the system-determined priority of the app - pictureProfilePriority = requested.appContentPriority; + pictureProfilePriority = int64_t(requested.appContentPriority) + INT_MAX; } if (forceUpdate || requested.what & layer_state_t::eDefaultFrameRateCompatibilityChanged) { @@ -528,4 +538,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 'e'; + case Composition::CURSOR: + return 'u'; + case Composition::SIDEBAND: + return 'd'; + case Composition::DISPLAY_DECORATION: + return 'a'; + case Composition::REFRESH_RATE_INDICATOR: + return 'f'; + 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 4d9a9ca06e..86ef6ca61e 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,25 +264,21 @@ void updateVisibility(LayerSnapshot& snapshot, bool visible) { } snapshot.isVisible = visible; - if (FlagManager::getInstance().skip_invisible_windows_in_input()) { - snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visible); - } 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()); } @@ -929,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); } @@ -969,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 @@ -999,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; + } } /** @@ -1162,7 +1178,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); @@ -1202,13 +1218,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..58c235ed91 100644 --- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp +++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp @@ -107,6 +107,7 @@ RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args) hdrMetadata.validTypes = 0; surfaceDamageRegion = Region::INVALID_REGION; cornerRadius = 0.0f; + clientDrawnCornerRadius = 0.0f; backgroundBlurRadius = 0; api = -1; hasColorTransform = false; @@ -348,6 +349,11 @@ 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; + } } ui::Size RequestedLayerState::getUnrotatedBufferSize(uint32_t displayRotationFlags) const { @@ -561,7 +567,7 @@ bool RequestedLayerState::needsInputInfo() const { return false; } - if ((sidebandStream != nullptr) || (externalTexture != nullptr)) { + if (hasBufferOrSidebandStream() || fillsColor()) { return true; } @@ -574,6 +580,15 @@ bool RequestedLayerState::needsInputInfo() const { windowInfo->inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL); } +bool RequestedLayerState::hasBufferOrSidebandStream() const { + return ((sidebandStream != nullptr) || (externalTexture != nullptr)); +} + +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 { return backgroundBlurRadius > 0 || blurRegions.size() > 0; } @@ -624,6 +639,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 7ddd7baf1e..723237940d 100644 --- a/services/surfaceflinger/FrontEnd/RequestedLayerState.h +++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.h @@ -23,7 +23,7 @@ #include "Scheduler/LayerInfo.h" #include "LayerCreationArgs.h" -#include "TransactionState.h" +#include "QueuedTransactionState.h" namespace android::surfaceflinger::frontend { using namespace ftl::flag_operators; @@ -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; diff --git a/services/surfaceflinger/FrontEnd/TransactionHandler.cpp b/services/surfaceflinger/FrontEnd/TransactionHandler.cpp index a1e8213132..5bf86e5705 100644 --- a/services/surfaceflinger/FrontEnd/TransactionHandler.cpp +++ b/services/surfaceflinger/FrontEnd/TransactionHandler.cpp @@ -28,7 +28,7 @@ namespace android::surfaceflinger::frontend { -void TransactionHandler::queueTransaction(TransactionState&& state) { +void TransactionHandler::queueTransaction(QueuedTransactionState&& state) { mLocklessTransactionQueue.push(std::move(state)); mPendingTransactionCount.fetch_add(1); SFTRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load())); @@ -45,9 +45,9 @@ void TransactionHandler::collectTransactions() { } } -std::vector<TransactionState> TransactionHandler::flushTransactions() { +std::vector<QueuedTransactionState> TransactionHandler::flushTransactions() { // Collect transaction that are ready to be applied. - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; TransactionFlushState flushState; flushState.queueProcessTime = systemTime(); // Transactions with a buffer pending on a barrier may be on a different applyToken @@ -76,7 +76,7 @@ std::vector<TransactionState> TransactionHandler::flushTransactions() { } void TransactionHandler::applyUnsignaledBufferTransaction( - std::vector<TransactionState>& transactions, TransactionFlushState& flushState) { + std::vector<QueuedTransactionState>& transactions, TransactionFlushState& flushState) { if (!flushState.queueWithUnsignaledBuffer) { return; } @@ -98,9 +98,9 @@ void TransactionHandler::applyUnsignaledBufferTransaction( } } -void TransactionHandler::popTransactionFromPending(std::vector<TransactionState>& transactions, - TransactionFlushState& flushState, - std::queue<TransactionState>& queue) { +void TransactionHandler::popTransactionFromPending( + std::vector<QueuedTransactionState>& transactions, TransactionFlushState& flushState, + std::queue<QueuedTransactionState>& queue) { auto& transaction = queue.front(); // Transaction is ready move it from the pending queue. flushState.firstTransaction = false; @@ -146,8 +146,8 @@ TransactionHandler::TransactionReadiness TransactionHandler::applyFilters( return ready; } -int TransactionHandler::flushPendingTransactionQueues(std::vector<TransactionState>& transactions, - TransactionFlushState& flushState) { +int TransactionHandler::flushPendingTransactionQueues( + std::vector<QueuedTransactionState>& transactions, TransactionFlushState& flushState) { int transactionsPendingBarrier = 0; auto it = mPendingTransactionQueues.begin(); while (it != mPendingTransactionQueues.end()) { diff --git a/services/surfaceflinger/FrontEnd/TransactionHandler.h b/services/surfaceflinger/FrontEnd/TransactionHandler.h index 00f6bcebe6..e78dd88be2 100644 --- a/services/surfaceflinger/FrontEnd/TransactionHandler.h +++ b/services/surfaceflinger/FrontEnd/TransactionHandler.h @@ -22,7 +22,7 @@ #include <vector> #include <LocklessQueue.h> -#include <TransactionState.h> +#include <QueuedTransactionState.h> #include <android-base/thread_annotations.h> #include <ftl/small_map.h> #include <ftl/small_vector.h> @@ -35,7 +35,7 @@ namespace surfaceflinger::frontend { class TransactionHandler { public: struct TransactionFlushState { - TransactionState* transaction; + QueuedTransactionState* transaction; bool firstTransaction = true; nsecs_t queueProcessTime = 0; // Layer handles that have transactions with buffers that are ready to be applied. @@ -61,9 +61,9 @@ public: bool hasPendingTransactions(); // Moves transactions from the lockless queue. void collectTransactions(); - std::vector<TransactionState> flushTransactions(); + std::vector<QueuedTransactionState> flushTransactions(); void addTransactionReadyFilter(TransactionFilter&&); - void queueTransaction(TransactionState&&); + void queueTransaction(QueuedTransactionState&&); struct StalledTransactionInfo { pid_t pid; @@ -81,14 +81,15 @@ private: // For unit tests friend class ::android::TestableSurfaceFlinger; - int flushPendingTransactionQueues(std::vector<TransactionState>&, TransactionFlushState&); - void applyUnsignaledBufferTransaction(std::vector<TransactionState>&, TransactionFlushState&); - void popTransactionFromPending(std::vector<TransactionState>&, TransactionFlushState&, - std::queue<TransactionState>&); + int flushPendingTransactionQueues(std::vector<QueuedTransactionState>&, TransactionFlushState&); + void applyUnsignaledBufferTransaction(std::vector<QueuedTransactionState>&, + TransactionFlushState&); + void popTransactionFromPending(std::vector<QueuedTransactionState>&, TransactionFlushState&, + std::queue<QueuedTransactionState>&); TransactionReadiness applyFilters(TransactionFlushState&); - std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash> + std::unordered_map<sp<IBinder>, std::queue<QueuedTransactionState>, IListenerHash> mPendingTransactionQueues; - LocklessQueue<TransactionState> mLocklessTransactionQueue; + LocklessQueue<QueuedTransactionState> mLocklessTransactionQueue; std::atomic<size_t> mPendingTransactionCount = 0; ftl::SmallVector<TransactionFilter, 2> mTransactionReadyFilters; diff --git a/services/surfaceflinger/FrontEnd/Update.h b/services/surfaceflinger/FrontEnd/Update.h index 4af27ab84d..f7dfeb84bc 100644 --- a/services/surfaceflinger/FrontEnd/Update.h +++ b/services/surfaceflinger/FrontEnd/Update.h @@ -19,15 +19,15 @@ #include <gui/DisplayInfo.h> #include "FrontEnd/LayerCreationArgs.h" +#include "QueuedTransactionState.h" #include "RequestedLayerState.h" -#include "TransactionState.h" namespace android::surfaceflinger::frontend { // Atomic set of changes affecting layer state. These changes are queued in binder threads and // applied every vsync. struct Update { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; std::vector<sp<Layer>> legacyLayers; std::vector<std::unique_ptr<frontend::RequestedLayerState>> newLayers; std::vector<LayerCreationArgs> layerCreationArgs; 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..95a7170fbb 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) { @@ -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..6af0f59d51 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -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/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/PowerAdvisor/Common.h b/services/surfaceflinger/PowerAdvisor/Common.h new file mode 100644 index 0000000000..b4a87dd9a4 --- /dev/null +++ b/services/surfaceflinger/PowerAdvisor/Common.h @@ -0,0 +1,28 @@ +/* + * 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 + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wconversion" +#include <aidl/android/adpf/ISessionManager.h> +#include <aidl/android/hardware/power/CompositionData.h> +#pragma clang diagnostic pop + +namespace android::adpf { +using namespace ::aidl::android::adpf; +namespace hal = ::aidl::android::hardware::power; +} // namespace android::adpf diff --git a/services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp b/services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp index c7d0b2c9ef..cd7210c627 100644 --- a/services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp +++ b/services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp @@ -28,25 +28,25 @@ #include <optional> #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> #include <binder/IServiceManager.h> -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" #include <powermanager/PowerHalController.h> #include <powermanager/PowerHintSessionWrapper.h> -#pragma clang diagnostic pop #include <common/FlagManager.h> #include "PowerAdvisor.h" - -namespace hal = aidl::android::hardware::power; +#include "SessionManager.h" namespace android::adpf::impl { +using namespace android::ftl::flag_operators; using aidl::android::hardware::common::fmq::SynchronizedReadWrite; using android::hardware::EventFlag; @@ -65,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, @@ -545,6 +547,18 @@ void PowerAdvisor::setTotalFrameTargetWorkDuration(Duration targetDuration) { mTotalFrameTargetDuration = targetDuration; } +std::shared_ptr<SessionManager> PowerAdvisor::getSessionManager() { + return mSessionManager; +} + +sp<IBinder> PowerAdvisor::getOrCreateSessionManagerForBinder(uid_t uid) { + // Flag guards the creation of SessionManager + if (mSessionManager == nullptr && FlagManager::getInstance().adpf_native_session_manager()) { + mSessionManager = ndk::SharedRefBase::make<SessionManager>(uid); + } + return AIBinder_toPlatformBinder(mSessionManager->asBinder().get()); +} + std::vector<DisplayId> PowerAdvisor::getOrderedDisplayIds( std::optional<TimePoint> DisplayTimingData::*sortBy) { std::vector<DisplayId> sortedDisplays; @@ -747,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 458b46d500..540a9df2ca 100644 --- a/services/surfaceflinger/PowerAdvisor/PowerAdvisor.h +++ b/services/surfaceflinger/PowerAdvisor/PowerAdvisor.h @@ -32,9 +32,14 @@ #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" using namespace std::chrono_literals; @@ -47,6 +52,8 @@ class PowerHintSessionWrapper; namespace adpf { +namespace hal = aidl::android::hardware::power; + class PowerAdvisor { public: virtual ~PowerAdvisor() = default; @@ -102,12 +109,38 @@ public: virtual void setDisplays(std::vector<DisplayId>& displayIds) = 0; // Sets the target duration for the entire pipeline including the gpu virtual void setTotalFrameTargetWorkDuration(Duration targetDuration) = 0; + // 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; // Send a hint about the imminent start of a new CPU workload virtual void notifyDisplayUpdateImminentAndCpuReset() = 0; + + // --- The following methods specifically run on binder threads --- + // Retrieve a SessionManager for HintManagerService to call + virtual sp<IBinder> getOrCreateSessionManagerForBinder(uid_t uid) = 0; }; namespace impl { @@ -146,11 +179,20 @@ public: void setCompositeEnd(TimePoint compositeEndTime) override; void setDisplays(std::vector<DisplayId>& displayIds) override; 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; + // --- The following methods specifically run on binder threads --- + sp<IBinder> getOrCreateSessionManagerForBinder(uid_t uid) override; + private: friend class PowerAdvisorTest; @@ -318,11 +360,18 @@ 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, class In> bool writeHintSessionMessage(In* elements, size_t count) REQUIRES(mHintSessionMutex); + + std::shared_ptr<SessionManager> mSessionManager; }; } // namespace impl diff --git a/services/surfaceflinger/PowerAdvisor/SessionLayerMap.cpp b/services/surfaceflinger/PowerAdvisor/SessionLayerMap.cpp new file mode 100644 index 0000000000..9f95163e2b --- /dev/null +++ b/services/surfaceflinger/PowerAdvisor/SessionLayerMap.cpp @@ -0,0 +1,93 @@ +/* + * 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 "SessionLayerMap.h" +#include <android/binder_libbinder.h> + +namespace android::adpf { + +void SessionLayerMap::notifySessionsDied(std::vector<int32_t>& sessionIds) { + for (int id : sessionIds) { + auto&& iter = mSessions.find(id); + if (iter != mSessions.end()) { + mSessions.erase(iter); + } + } +} + +void SessionLayerMap::notifyLayersDied(std::vector<int32_t>& layers) { + for (auto&& layer : layers) { + auto&& iter = mLayers.find(layer); + if (iter != mLayers.end()) { + mLayers.erase(iter); + } + } +} + +bool SessionLayerMap::bindSessionIDToLayers(int sessionId, const std::vector<int32_t>& layerIds) { + // If there is no association, just drop from map + if (layerIds.empty()) { + mSessions.erase(sessionId); + return false; + } + + // Ensure session exists + if (!mSessions.contains(sessionId)) { + mSessions.emplace(sessionId, MappedType(sessionId, mLayers)); + } + + MappedType& session = mSessions.at(sessionId); + std::set<int32_t> newLinks; + + // For each incoming link + for (auto&& layerId : layerIds) { + auto&& iter = mLayers.find(layerId); + + // If it's not in the map, add it + if (iter == mLayers.end()) { + mLayers.emplace(layerId, MappedType(layerId, mSessions)); + } + + // Make a ref to it in the session's new association map + newLinks.insert(layerId); + } + + session.swapLinks(std::move(newLinks)); + return true; +} + +void SessionLayerMap::getAssociatedSessions(int32_t layerId, std::vector<int32_t>& sessionIdsOut) { + sessionIdsOut.clear(); + auto&& iter = mLayers.find(layerId); + + if (iter == mLayers.end()) { + return; + } + + // Dump the internal association set into this vector + sessionIdsOut.insert(sessionIdsOut.begin(), iter->second.mLinks.begin(), + iter->second.mLinks.end()); +} + +void SessionLayerMap::getCurrentlyRelevantLayers( + std::unordered_set<int32_t>& currentlyRelevantLayers) { + currentlyRelevantLayers.clear(); + for (auto&& layer : mLayers) { + currentlyRelevantLayers.insert(layer.first); + } +} + +} // namespace android::adpf
\ No newline at end of file diff --git a/services/surfaceflinger/PowerAdvisor/SessionLayerMap.h b/services/surfaceflinger/PowerAdvisor/SessionLayerMap.h new file mode 100644 index 0000000000..51808a65fc --- /dev/null +++ b/services/surfaceflinger/PowerAdvisor/SessionLayerMap.h @@ -0,0 +1,111 @@ +/* + * 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 <log/log.h> +#include <set> +#include <unordered_map> +#include <unordered_set> + +namespace android::adpf { + +class SessionLayerMap { +public: + // Inform the SessionLayerMap about dead sessions + void notifySessionsDied(std::vector<int32_t>& sessionIds); + // Inform the SessionLayerMap about dead layers + void notifyLayersDied(std::vector<int32_t>& layers); + // Associate a session with a specific set of layer ids + bool bindSessionIDToLayers(int sessionId, const std::vector<int32_t>& layerIds); + // Get the set of sessions that are mapped to a specific layer id + void getAssociatedSessions(int32_t layerId, std::vector<int32_t>& sessionIdsOut); + // Get the set of layers that are currently being tracked + void getCurrentlyRelevantLayers(std::unordered_set<int32_t>& currentlyRelevantLayers); + +private: + struct MappedType { + MappedType(int32_t id, std::unordered_map<int32_t, MappedType>& otherList) + : mId(id), mOtherList(otherList) {}; + MappedType() = delete; + ~MappedType() { swapLinks({}); } + + // Replace the set of associated IDs for this mapped type with a different set of IDs, + // updating only associations which have changed between the two sets + void swapLinks(std::set<int32_t>&& incoming) { + auto&& oldIter = mLinks.begin(); + auto&& newIter = incoming.begin(); + + // Dump all outdated values and insert new ones + while (oldIter != mLinks.end() || newIter != incoming.end()) { + // If there is a value in the new set but not the old set + // We should have already ensured what we're linking to exists + if (oldIter == mLinks.end() || (newIter != incoming.end() && *newIter < *oldIter)) { + addRemoteAssociation(*newIter); + ++newIter; + continue; + } + + // If there is a value in the old set but not the new set + if (newIter == incoming.end() || (oldIter != mLinks.end() && *oldIter < *newIter)) { + dropRemoteAssociation(*oldIter); + ++oldIter; + continue; + } + + // If they're the same, skip + if (*oldIter == *newIter) { + ++oldIter; + ++newIter; + continue; + } + } + + mLinks.swap(incoming); + } + + void addRemoteAssociation(int32_t other) { + auto&& iter = mOtherList.find(other); + if (iter != mOtherList.end()) { + iter->second.mLinks.insert(mId); + } else { + ALOGE("Existing entry in SessionLayerMap, link failed"); + } + } + + void dropRemoteAssociation(int32_t other) { + auto&& iter = mOtherList.find(other); + if (iter != mOtherList.end()) { + iter->second.mLinks.erase(mId); + if (iter->second.mLinks.empty()) { + // This only erases them from the map, not from general tracking + mOtherList.erase(iter); + } + } else { + ALOGE("Missing entry in SessionLayerMap, unlinking failed"); + } + } + + int32_t mId; + std::set<int> mLinks; + std::unordered_map<int32_t, MappedType>& mOtherList; + }; + + std::unordered_map<int32_t, MappedType> mSessions; + std::unordered_map<int32_t, MappedType> mLayers; +}; + +} // namespace android::adpf diff --git a/services/surfaceflinger/PowerAdvisor/SessionManager.cpp b/services/surfaceflinger/PowerAdvisor/SessionManager.cpp new file mode 100644 index 0000000000..a855f07914 --- /dev/null +++ b/services/surfaceflinger/PowerAdvisor/SessionManager.cpp @@ -0,0 +1,93 @@ +/* + * 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 "PowerAdvisor/SessionManager.h" +#include <android/binder_libbinder.h> +#include <android/binder_status.h> +#include <binder/IPCThreadState.h> +#include "FrontEnd/LayerHandle.h" +#include "Layer.h" +#include "SurfaceFlinger.h" + +namespace android::adpf { + +SessionManager::SessionManager(uid_t uid) : mUid(uid) {} + +ndk::ScopedAStatus SessionManager::associateSessionToLayers( + int32_t sessionId, int32_t ownerUid, const std::vector<::ndk::SpAIBinder>& layerTokens) { + std::scoped_lock lock{mSessionManagerMutex}; + + std::vector<int32_t> layerIds; + + for (auto&& token : layerTokens) { + auto platformToken = AIBinder_toPlatformBinder(token.get()); + + // Get the layer id for it + int32_t layerId = + static_cast<int32_t>(surfaceflinger::LayerHandle::getLayerId(platformToken)); + auto&& iter = mTrackedLayerData.find(layerId); + + // Ensure it is being tracked + if (iter == mTrackedLayerData.end()) { + mTrackedLayerData.emplace(layerId, LayerData{.layerId = layerId}); + } + layerIds.push_back(layerId); + } + + // Register the session then track it + if (mMap.bindSessionIDToLayers(sessionId, layerIds) && + !mTrackedSessionData.contains(sessionId)) { + mTrackedSessionData.emplace(sessionId, + SessionData{.sessionId = sessionId, .uid = ownerUid}); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus SessionManager::trackedSessionsDied(const std::vector<int32_t>& sessionIds) { + std::scoped_lock lock{mSessionManagerMutex}; + for (int sessionId : sessionIds) { + mDeadSessions.push_back(sessionId); + mTrackedSessionData.erase(sessionId); + } + + return ndk::ScopedAStatus::ok(); +} + +void SessionManager::updateTrackingState( + const std::vector<std::pair<uint32_t, std::string>>& handles) { + std::scoped_lock lock{mSessionManagerMutex}; + std::vector<int32_t> deadLayers; + for (auto&& handle : handles) { + int32_t handleId = static_cast<int32_t>(handle.first); + auto it = mTrackedLayerData.find(handleId); + if (it != mTrackedLayerData.end()) { + // Track any dead layers to remove from the mapping + mTrackedLayerData.erase(it); + deadLayers.push_back(it->first); + } + } + mMap.notifyLayersDied(deadLayers); + mMap.notifySessionsDied(mDeadSessions); + + mDeadSessions.clear(); + mMap.getCurrentlyRelevantLayers(mCurrentlyRelevantLayers); +} + +bool SessionManager::isLayerRelevant(int32_t layerId) { + return mCurrentlyRelevantLayers.contains(layerId); +} + +} // namespace android::adpf
\ No newline at end of file diff --git a/services/surfaceflinger/PowerAdvisor/SessionManager.h b/services/surfaceflinger/PowerAdvisor/SessionManager.h new file mode 100644 index 0000000000..93a80b55ab --- /dev/null +++ b/services/surfaceflinger/PowerAdvisor/SessionManager.h @@ -0,0 +1,102 @@ +/* + * 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 <aidl/android/adpf/BnSessionManager.h> +#include <sys/types.h> + +#include <utils/Thread.h> +#include "Common.h" +#include "SessionLayerMap.h" + +#include <string> + +namespace android { + +class Layer; + +namespace adpf { +namespace impl { + +class PowerAdvisor; + +} + +// Talks to HMS to manage sessions for PowerHAL +class SessionManager : public BnSessionManager { +public: + SessionManager(uid_t uid); + + // ISessionManager binder methods + ndk::ScopedAStatus trackedSessionsDied(const std::vector<int32_t>& in_sessionId) override; + ndk::ScopedAStatus associateSessionToLayers( + int32_t sessionId, int32_t ownerUid, + const std::vector<::ndk::SpAIBinder>& layers) override; + + // Update the lifecycles of any tracked sessions or layers. This is intended to accepts the + // "destroyedHandles" object from updateLayerSnapshots in SF, and should reflect that type + void updateTrackingState(const std::vector<std::pair<uint32_t, std::string>>& handles); + +private: + // Session metadata tracked by the mTrackedSessionData map + struct SessionData { + int32_t sessionId; + int uid; + }; + + // Layer metadata tracked by the mTrackedSessionData map + struct LayerData { + int32_t layerId; + }; + + // Checks if the layer is currently associated with a specific session in the SessionLayerMap + // This helps us know which layers might be included in an update for the HAL + bool isLayerRelevant(int32_t layerId); + + // The UID of whoever created our ISessionManager connection + const uid_t mUid; + + // State owned by the main thread + + // Set of layers that are currently being tracked in the SessionLayerMap. This is used to + // filter out which layers we actually care about during the latching process + std::unordered_set<int32_t> mCurrentlyRelevantLayers; + + // Tracks active associations between sessions and layers. Items in this map can be thought of + // as "active" connections, and any session or layer not in this map will not receive updates or + // be collected in SurfaceFlinger + SessionLayerMap mMap; + + // The list of currently-living layers which have ever been tracked, this is used to persist any + // data we want to track across potential mapping disconnects, and to determine when to send + // death updates + std::unordered_map<int32_t, LayerData> mTrackedLayerData; + + // The list of currently-living sessions which have ever been tracked, this is used to persist + // any data we want to track across mapping disconnects + std::unordered_map<int32_t, SessionData> mTrackedSessionData; + + // State owned by mSessionManagerMutex + + std::mutex mSessionManagerMutex; + + // The list of sessions that have died since we last called updateTrackingState + std::vector<int32_t> mDeadSessions GUARDED_BY(mSessionManagerMutex); +}; + +} // namespace adpf +} // namespace android
\ No newline at end of file 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/TransactionState.h b/services/surfaceflinger/QueuedTransactionState.h index e5d648194f..86683da26c 100644 --- a/services/surfaceflinger/TransactionState.h +++ b/services/surfaceflinger/QueuedTransactionState.h @@ -16,14 +16,14 @@ #pragma once -#include <condition_variable> #include <memory> -#include <mutex> #include <vector> #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 <system/window.h> @@ -47,18 +47,20 @@ public: uint32_t touchCropId = UNASSIGNED_LAYER_ID; }; -struct TransactionState { - TransactionState() = default; +struct QueuedTransactionState { + QueuedTransactionState() = default; - TransactionState(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) + 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), @@ -148,6 +150,7 @@ struct TransactionState { 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 21d3396ebe..514adac20c 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; @@ -346,20 +345,21 @@ void RegionSamplingThread::captureSample() { constexpr bool kRegionSampling = true; constexpr bool kGrayscale = false; constexpr bool kIsProtected = false; - constexpr bool kAttachGainmap = 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.displayId = 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, kAttachGainmap, 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/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp index 6e2b943509..8c22de142d 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp @@ -504,7 +504,7 @@ FrameRateCompatibility LayerInfo::FrameRate::convertCompatibility(int8_t compati return FrameRateCompatibility::Exact; case ANATIVEWINDOW_FRAME_RATE_MIN: return FrameRateCompatibility::Min; - case ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE: + case ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_AT_LEAST: return FrameRateCompatibility::Gte; case ANATIVEWINDOW_FRAME_RATE_NO_VOTE: return FrameRateCompatibility::NoVote; 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.h b/services/surfaceflinger/Scheduler/Scheduler.h index a2cdd460ca..3fdddac52a 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -209,7 +209,6 @@ public: ftl::FakeGuard guard(kMainThreadContext); resyncToHardwareVsyncLocked(id, allowToEnable, modePtr); } - void resync() override EXCLUDES(mDisplayLock); void forceNextResync() { mLastResyncTime = 0; } // Passes a vsync sample to VsyncController. Returns true if @@ -471,6 +470,7 @@ private: bool throttleVsync(TimePoint, uid_t) override; // Get frame interval Period getVsyncPeriod(uid_t) override EXCLUDES(mDisplayLock); + void resync() override EXCLUDES(mDisplayLock); void onExpectedPresentTimePosted(TimePoint expectedPresentTime) override EXCLUDES(mDisplayLock); std::unique_ptr<EventThread> mRenderEventThread; diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp index ff360b754c..b9c79df9b7 100644 --- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp +++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp @@ -206,7 +206,11 @@ 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 = 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/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..af6d4d30e4 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.cpp +++ b/services/surfaceflinger/ScreenCaptureOutput.cpp @@ -16,22 +16,28 @@ #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, std::optional<DisplayId>, 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.displayId, + 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 +51,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 (args.displayId) { + base::StringAppendF(&name, " for %" PRIu64, args.displayId.value().value); } output->setName(name); } @@ -62,11 +68,14 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp } ScreenCaptureOutput::ScreenCaptureOutput( - const RenderArea& renderArea, const compositionengine::Output::ColorProfile& colorProfile, + const Rect sourceCrop, std::optional<DisplayId> displayId, + const compositionengine::Output::ColorProfile& colorProfile, float layerAlpha, bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots, bool enableLocalTonemapping) - : mRenderArea(renderArea), + : mSourceCrop(sourceCrop), + mDisplayId(displayId), mColorProfile(colorProfile), + mLayerAlpha(layerAlpha), mRegionSampling(regionSampling), mDimInGammaSpaceForEnhancedScreenshots(dimInGammaSpaceForEnhancedScreenshots), mEnableLocalTonemapping(enableLocalTonemapping) {} @@ -81,7 +90,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 +113,84 @@ 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 (mDisplayId) { + const auto id = PhysicalDisplayId::tryCast(mDisplayId.value()); + if (id) { + auto& hwc = getCompositionEngine().getHwComposer(); + hwc.getLuts(*id, 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 +208,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..b3e98b1a32 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; + std::optional<DisplayId> displayId; + 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, std::optional<DisplayId> displayId, 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 std::optional<DisplayId> mDisplayId; 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 05db927402..35cb63ea89 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -37,12 +37,14 @@ #include <android/hardware/configstore/1.1/types.h> #include <android/native_window.h> #include <android/os/IInputFlinger.h> +#include <android_os.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> #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> @@ -126,7 +128,6 @@ #include <gui/SchedulingPolicy.h> #include <gui/SyncScreenCaptureListener.h> #include <ui/DisplayIdentification.h> -#include "ActivePictureUpdater.h" #include "BackgroundExecutor.h" #include "Client.h" #include "ClientCache.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" @@ -742,7 +740,10 @@ void SurfaceFlinger::bootFinished() { mBootFinished = true; FlagManager::getMutableInstance().markBootCompleted(); - ::tracing_perfetto::registerWithPerfetto(); + if (android::os::perfetto_sdk_tracing()) { + ::tracing_perfetto::registerWithPerfetto(); + } + mInitBootPropsFuture.wait(); mRenderEnginePrimeCacheFuture.wait(); @@ -876,6 +877,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; @@ -917,7 +920,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); @@ -1063,7 +1067,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"); @@ -1158,8 +1163,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; @@ -1281,9 +1286,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; @@ -1358,7 +1363,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 */); @@ -1377,6 +1383,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: @@ -1444,30 +1459,36 @@ status_t SurfaceFlinger::setActiveModeFromBackdoor(const sp<display::DisplayToke return future.get(); } -void SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) { +bool SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) { SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); const auto pendingModeOpt = mDisplayModeController.getPendingMode(displayId); if (!pendingModeOpt) { // There is no pending mode change. This can happen if the active // display changed and the mode change happened on a different display. - return; + return true; } 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(); - - // processDisplayChangesLocked will update all necessary components so we're done here. - return; + 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(), @@ -1475,9 +1496,12 @@ void 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); } + + return true; } void SurfaceFlinger::dropModeRequest(PhysicalDisplayId displayId) { @@ -1525,8 +1549,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; } @@ -1547,6 +1572,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); @@ -2282,12 +2316,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) { @@ -2449,9 +2483,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"); @@ -2478,8 +2514,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, @@ -2633,7 +2681,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(); @@ -2659,7 +2707,10 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId, for (const auto [displayId, _] : frameTargets) { if (mDisplayModeController.isModeSetPending(displayId)) { - finalizeDisplayModeChange(displayId); + if (!finalizeDisplayModeChange(displayId)) { + mScheduler->scheduleFrame(); + return false; + } } } } @@ -2677,7 +2728,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 @@ -2751,6 +2802,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; @@ -2777,6 +2829,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(); @@ -2788,12 +2842,45 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays); refreshArgs.outputs.reserve(displays.size()); + // Track layer stacks of physical displays that might be added to CompositionEngine + // 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; + for (auto& [_, display] : displays) { + const auto id = PhysicalDisplayId::tryCast(display->getId()); + if (id && frameTargeters.contains(*id)) { + physicalDisplayLayerStacks.try_emplace(*id, display->getLayerStack()); + } + } + + // Tracks layer stacks of displays that are added to CompositionEngine output. + ui::DisplayMap<ui::LayerStack, ftl::Unit> outputLayerStacks; + 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 true; + }; + // Add outputs for physical displays. for (const auto& [id, targeter] : frameTargeters) { ftl::FakeGuard guard(mStateLock); if (const auto display = getCompositionDisplayLocked(id)) { - refreshArgs.outputs.push_back(display); + const auto layerStack = physicalDisplayLayerStacks.get(id)->get(); + if (isUniqueOutputLayerStack(display->getId(), layerStack)) { + refreshArgs.outputs.push_back(display); + } } refreshArgs.frameTargets.try_emplace(id, &targeter->target()); @@ -2810,7 +2897,9 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( if (!refreshRate.isValid() || mScheduler->isVsyncInPhase(pacesetterTarget.frameBeginTime(), refreshRate)) { - refreshArgs.outputs.push_back(display->getCompositionDisplay()); + if (isUniqueOutputLayerStack(display->getId(), display->getLayerStack())) { + refreshArgs.outputs.push_back(display->getCompositionDisplay()); + } } } } @@ -2906,18 +2995,91 @@ 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); } if (com_android_graphics_libgui_flags_apply_picture_profiles()) { - mActivePictureUpdater.onLayerComposed(*layer, *layerFE, compositionResult); + 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()); @@ -3171,12 +3333,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; { @@ -3226,8 +3388,8 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, std::vector<std::pair<std::shared_ptr<compositionengine::Display>, sp<HdrLayerInfoReporter>>> hdrInfoListeners; bool haveNewHdrInfoListeners = false; - sp<gui::IActivePictureListener> activePictureListener; - bool haveNewActivePictureListener = false; + ActivePictureTracker::Listeners activePictureListenersToAdd; + ActivePictureTracker::Listeners activePictureListenersToRemove; { Mutex::Autolock lock(mStateLock); if (mFpsReporter) { @@ -3249,9 +3411,8 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, haveNewHdrInfoListeners = mAddingHDRLayerInfoListener; // grab this with state lock mAddingHDRLayerInfoListener = false; - activePictureListener = mActivePictureListener; - haveNewActivePictureListener = mHaveNewActivePictureListener; - mHaveNewActivePictureListener = false; + std::swap(activePictureListenersToAdd, mActivePictureListenersToAdd); + std::swap(activePictureListenersToRemove, mActivePictureListenersToRemove); } if (haveNewHdrInfoListeners || mHdrLayerInfoChanged) { @@ -3315,14 +3476,10 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, mHdrLayerInfoChanged = false; if (com_android_graphics_libgui_flags_apply_picture_profiles()) { - // Track, update and notify changes to active pictures - layers that are undergoing picture - // processing - if (mActivePictureUpdater.updateAndHasChanged() || haveNewActivePictureListener) { - if (activePictureListener) { - activePictureListener->onActivePicturesChanged( - mActivePictureUpdater.getActivePictures()); - } - } + // Track, update and notify changes to active pictures - layers that are undergoing + // picture processing + mActivePictureTracker.updateAndNotifyListeners(activePictureListenersToAdd, + activePictureListenersToRemove); } mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */); @@ -3332,13 +3489,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 = @@ -3563,13 +3714,13 @@ 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) { + if (event == HWComposer::HotplugEvent::Connected) { const auto activeModeIdOpt = processHotplugConnect(displayId, hwcDisplayId, std::move(*info), displayString.c_str()); @@ -3626,6 +3777,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()) { @@ -3634,14 +3786,17 @@ std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDispl deviceProductInfo = snapshot.deviceProductInfo(); } + // 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, + 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; } @@ -3650,13 +3805,14 @@ std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDispl const ui::DisplayConnectionType connectionType = getHwComposer().getDisplayConnectionType(displayId); - mPhysicalDisplays.try_emplace(displayId, token, displayId, connectionType, + mPhysicalDisplays.try_emplace(displayId, token, displayId, info.port, connectionType, std::move(displayModes), std::move(colorModes), std::move(info.deviceProductInfo)); DisplayDeviceState state; state.physical = {.id = displayId, .hwcDisplayId = hwcDisplayId, + .port = info.port, .activeMode = std::move(activeMode)}; if (mIsHdcpViaNegVsync) { state.isSecure = connectionType == ui::DisplayConnectionType::Internal; @@ -3877,9 +4033,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); @@ -3975,7 +4128,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); @@ -4001,6 +4154,35 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, 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)) { @@ -4012,13 +4194,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(); } } } @@ -4545,7 +4723,6 @@ void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule sche SFTRACE_INT("mTransactionFlags", transactionFlags); if (const bool scheduled = transactionFlags & mask; !scheduled) { - mScheduler->resync(); scheduleCommit(frameHint); } else if (frameHint == FrameHint::kActive) { // Even if the next frame is already scheduled, we should reset the idle timer @@ -4715,16 +4892,18 @@ void SurfaceFlinger::addTransactionReadyFilters() { // For tests only bool SurfaceFlinger::flushTransactionQueues() { mTransactionHandler.collectTransactions(); - std::vector<TransactionState> transactions = mTransactionHandler.flushTransactions(); + std::vector<QueuedTransactionState> transactions = mTransactionHandler.flushTransactions(); return applyTransactions(transactions); } -bool SurfaceFlinger::applyTransactions(std::vector<TransactionState>& transactions) { +bool SurfaceFlinger::applyTransactions(std::vector<QueuedTransactionState>& transactions) + EXCLUDES(mStateLock) { Mutex::Autolock lock(mStateLock); return applyTransactionsLocked(transactions); } -bool SurfaceFlinger::applyTransactionsLocked(std::vector<TransactionState>& transactions) { +bool SurfaceFlinger::applyTransactionsLocked(std::vector<QueuedTransactionState>& transactions) + REQUIRES(mStateLock) { bool needsTraversal = false; // Now apply all transactions. for (auto& transaction : transactions) { @@ -4814,8 +4993,15 @@ status_t SurfaceFlinger::setTransactionState( const int originPid = ipc->getCallingPid(); const int originUid = ipc->getCallingUid(); uint32_t permissions = LayerStatePermissions::getTransactionPermissions(originPid, originUid); + ftl::Flags<adpf::Workload> queuedWorkload; for (auto& composerState : states) { 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) { @@ -4838,6 +5024,10 @@ status_t SurfaceFlinger::setTransactionState( flags &= ~(eEarlyWakeupStart | eEarlyWakeupEnd); } } + if (flags & eEarlyWakeupStart) { + queuedWorkload |= adpf::Workload::WAKEUP; + } + mPowerAdvisor->setQueuedWorkload(queuedWorkload); const int64_t postTime = systemTime(); @@ -4885,22 +5075,23 @@ status_t SurfaceFlinger::setTransactionState( } } - TransactionState state{frameTimelineInfo, - resolvedStates, - displays, - flags, - applyToken, - std::move(inputWindowCommands), - desiredPresentTime, - isAutoTimestamp, - std::move(uncacheBufferIds), - postTime, - hasListenerCallbacks, - listenerCallbacks, - originPid, - originUid, - transactionId, - mergedTransactionIds}; + QueuedTransactionState state{frameTimelineInfo, + resolvedStates, + displays, + flags, + applyToken, + std::move(inputWindowCommands), + desiredPresentTime, + isAutoTimestamp, + std::move(uncacheBufferIds), + postTime, + hasListenerCallbacks, + listenerCallbacks, + originPid, + originUid, + transactionId, + mergedTransactionIds}; + state.workloadHint = queuedWorkload; if (mTransactionTracing) { mTransactionTracing->addQueuedTransaction(state); @@ -4929,15 +5120,13 @@ status_t SurfaceFlinger::setTransactionState( 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, + 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) REQUIRES(mStateLock) { uint32_t transactionFlags = 0; // start and end registration for listeners w/ no surface so they can get their callback. Note @@ -4985,7 +5174,7 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin } bool SurfaceFlinger::applyAndCommitDisplayTransactionStatesLocked( - std::vector<TransactionState>& transactions) { + std::vector<QueuedTransactionState>& transactions) { bool needsTraversal = false; uint32_t transactionFlags = 0; for (auto& transaction : transactions) { @@ -5089,7 +5278,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; @@ -5411,7 +5600,7 @@ void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer, uint32_t layerId) { } void SurfaceFlinger::initializeDisplays() { - TransactionState state; + QueuedTransactionState state; state.inputWindowCommands = mInputWindowCommands; const nsecs_t now = systemTime(); state.desiredPresentTime = now; @@ -5426,7 +5615,7 @@ void SurfaceFlinger::initializeDisplays() { state.displays.push(DisplayState(display.token(), ui::LayerStack::fromValue(layerStack++))); } - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(state); { @@ -6628,8 +6817,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"); @@ -6727,10 +6917,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; } @@ -6739,7 +6929,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); } } @@ -6822,11 +7012,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); @@ -7018,7 +7207,7 @@ status_t SurfaceFlinger::setSchedFifo(bool enabled) { 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 { @@ -7058,14 +7247,13 @@ status_t SurfaceFlinger::setSchedAttr(bool enabled) { 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)) { @@ -7114,9 +7302,13 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, } wp<const DisplayDevice> displayWeak; + DisplayId displayId; 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); @@ -7126,11 +7318,14 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, return; } displayWeak = display; + displayId = display->getId(); 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) { @@ -7149,19 +7344,21 @@ 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.displayId = displayId; + 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, - captureArgs.attachGainmap, captureListener); + captureArgs.allowProtected, captureArgs.grayscale, captureListener); } void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args, @@ -7169,6 +7366,9 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args ui::LayerStack layerStack; wp<const DisplayDevice> displayWeak; ui::Size size; + Rect layerStackSpaceRect; + bool displayIsSecure; + { Mutex::Autolock lock(mStateLock); @@ -7181,7 +7381,9 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args displayWeak = display; layerStack = display->getLayerStack(); + layerStackSpaceRect = display->getLayerStackSpaceRect(); size = display->getLayerStackSpaceRect().getSize(); + displayIsSecure = display->isSecure(); } size.width *= args.frameScaleX; @@ -7210,15 +7412,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, args.attachGainmap, captureListener); + ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = displayWeak; + screenshotArgs.displayId = displayId; + 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) { @@ -7320,17 +7525,18 @@ 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, - captureArgs.attachGainmap, captureListener); + captureArgs.allowProtected, captureArgs.grayscale, captureListener); } // Creates a Future release fence for a layer and keeps track of it in a list to @@ -7359,15 +7565,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 @@ -7380,15 +7588,15 @@ 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, bool attachGainmap, + bool allowProtected, bool grayscale, const sp<IScreenCaptureListener>& captureListener) { SFTRACE_CALL(); @@ -7401,7 +7609,15 @@ 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())); + }); const bool supportsProtected = getRenderEngine().supportsProtectedContent(); bool hasProtectedLayer = false; @@ -7431,35 +7647,80 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), renderengine::impl::ExternalTexture::Usage:: WRITEABLE); + + std::shared_ptr<renderengine::impl::ExternalTexture> hdrTexture; + std::shared_ptr<renderengine::impl::ExternalTexture> gainmapTexture; + + 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 */, + buffer->getUsage(), "screenshot-hdr"); + const auto gainmapBuffer = + getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(), + buffer->getPixelFormat(), 1 /* layerCount */, + buffer->getUsage(), "screenshot-gainmap"); + + const status_t hdrBufferStatus = hdrBuffer->initCheck(); + const status_t gainmapBufferStatus = gainmapBuffer->initCheck(); + + if (hdrBufferStatus != OK || gainmapBufferStatus != -OK) { + if (hdrBufferStatus != OK) { + ALOGW("%s: Buffer failed to allocate for hdr: %d. Screenshoting SDR instead.", + __func__, hdrBufferStatus); + } else { + ALOGW("%s: Buffer failed to allocate for gainmap: %d. Screenshoting SDR instead.", + __func__, gainmapBufferStatus); + } + } else { + hdrTexture = std::make_shared< + renderengine::impl::ExternalTexture>(hdrBuffer, getRenderEngine(), + renderengine::impl::ExternalTexture:: + Usage::WRITEABLE); + gainmapTexture = std::make_shared< + renderengine::impl::ExternalTexture>(gainmapBuffer, getRenderEngine(), + renderengine::impl::ExternalTexture:: + Usage::WRITEABLE); + } + } + auto futureFence = - captureScreenshot(renderAreaBuilder, texture, false /* regionSampling */, grayscale, - isProtected, attachGainmap, captureListener, displayState, layers); + 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) { @@ -7467,112 +7728,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, bool attachGainmap, + ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer, + bool regionSampling, bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener, - std::optional<OutputCompositionState>& displayState, - std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) { + 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 = - renderScreenImpl(renderArea.get(), buffer, regionSampling, grayscale, isProtected, - captureResults, displayState, layers); - - if (captureResults.capturedHdrLayers && attachGainmap && - FlagManager::getInstance().true_hdr_screenshots()) { - sp<GraphicBuffer> hdrBuffer = - getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(), - HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */, - buffer->getUsage(), "screenshot-hdr"); - sp<GraphicBuffer> gainmapBuffer = - getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(), - buffer->getPixelFormat(), 1 /* layerCount */, - buffer->getUsage(), "screenshot-gainmap"); - - const status_t bufferStatus = hdrBuffer->initCheck(); - const status_t gainmapBufferStatus = gainmapBuffer->initCheck(); - - if (bufferStatus != OK) { - ALOGW("%s: Buffer failed to allocate for hdr: %d. Screenshoting SDR instead.", __func__, - bufferStatus); - } else if (gainmapBufferStatus != OK) { - ALOGW("%s: Buffer failed to allocate for gainmap: %d. Screenshoting SDR instead.", - __func__, gainmapBufferStatus); - } else { - captureResults.optionalGainMap = gainmapBuffer; - const auto hdrTexture = std::make_shared< - renderengine::impl::ExternalTexture>(hdrBuffer, getRenderEngine(), - renderengine::impl::ExternalTexture:: - Usage::WRITEABLE); - const auto gainmapTexture = std::make_shared< - renderengine::impl::ExternalTexture>(gainmapBuffer, getRenderEngine(), - renderengine::impl::ExternalTexture:: - Usage::WRITEABLE); - ScreenCaptureResults unusedResults; - ftl::SharedFuture<FenceResult> hdrRenderFuture = - renderScreenImpl(renderArea.get(), hdrTexture, regionSampling, grayscale, - isProtected, unusedResults, displayState, layers); - - renderFuture = - ftl::Future(std::move(renderFuture)) - .then([&, hdrRenderFuture = std::move(hdrRenderFuture), - displayBrightnessNits, sdrWhitePointNits, - dataspace = captureResults.capturedDataspace, buffer, hdrTexture, - gainmapTexture](FenceResult fenceResult) -> FenceResult { - if (!fenceResult.ok()) { - return fenceResult; - } - - auto hdrFenceResult = hdrRenderFuture.get(); - - if (!hdrFenceResult.ok()) { - return hdrFenceResult; - } + ftl::SharedFuture<FenceResult> renderFuture; + + float hdrSdrRatio = args.displayBrightnessNits / args.sdrWhitePointNits; + + if (hdrBuffer && gainmapBuffer) { + ftl::SharedFuture<FenceResult> hdrRenderFuture = + renderScreenImpl(args, hdrBuffer, regionSampling, grayscale, isProtected, + captureResults, layers); + captureResults.buffer = buffer->getBuffer(); + captureResults.optionalGainMap = gainmapBuffer->getBuffer(); + + renderFuture = + ftl::Future(std::move(hdrRenderFuture)) + .then([&, hdrSdrRatio, dataspace = captureResults.capturedDataspace, buffer, + hdrBuffer, gainmapBuffer](FenceResult fenceResult) -> FenceResult { + if (!fenceResult.ok()) { + return fenceResult; + } - return getRenderEngine() - .drawGainmap(buffer, fenceResult.value()->get(), hdrTexture, - hdrFenceResult.value()->get(), - displayBrightnessNits / sdrWhitePointNits, - static_cast<ui::Dataspace>(dataspace), - gainmapTexture) - .get(); - }) - .share(); - }; + return getRenderEngine() + .tonemapAndDrawGainmap(hdrBuffer, fenceResult.value()->get(), + hdrSdrRatio, + static_cast<ui::Dataspace>(dataspace), + buffer, gainmapBuffer) + .get(); + }) + .share(); + } else { + 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); }) @@ -7582,10 +7797,9 @@ 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, - std::optional<OutputCompositionState>& displayState, - std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) { + const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) { SFTRACE_CALL(); for (auto& [_, layerFE] : layers) { @@ -7593,57 +7807,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}; @@ -7653,13 +7853,12 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( } auto present = [this, buffer = capturedBuffer, dataspace = captureResults.capturedDataspace, - sdrWhitePointNits, displayBrightnessNits, grayscale, isProtected, - layers = std::move(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()); @@ -7680,9 +7879,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) { @@ -7690,23 +7890,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, + .displayId = args.displayId, + .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}); @@ -7795,9 +8005,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); } @@ -8186,12 +8395,20 @@ void SurfaceFlinger::updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t con })); } -void SurfaceFlinger::setActivePictureListener(const sp<gui::IActivePictureListener>& listener) { - if (com_android_graphics_libgui_flags_apply_picture_profiles()) { - Mutex::Autolock lock(mStateLock); - mActivePictureListener = listener; - mHaveNewActivePictureListener = listener != nullptr; - } +void SurfaceFlinger::addActivePictureListener(const sp<gui::IActivePictureListener>& listener) { + Mutex::Autolock lock(mStateLock); + std::erase_if(mActivePictureListenersToRemove, [listener](const auto& otherListener) { + return IInterface::asBinder(listener) == IInterface::asBinder(otherListener); + }); + mActivePictureListenersToAdd.push_back(listener); +} + +void SurfaceFlinger::removeActivePictureListener(const sp<gui::IActivePictureListener>& listener) { + Mutex::Autolock lock(mStateLock); + std::erase_if(mActivePictureListenersToAdd, [listener](const auto& otherListener) { + return IInterface::asBinder(listener) == IInterface::asBinder(otherListener); + }); + mActivePictureListenersToRemove.push_back(listener); } std::shared_ptr<renderengine::ExternalTexture> SurfaceFlinger::getExternalTextureFromBufferData( @@ -8570,8 +8787,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(); } @@ -9144,11 +9361,20 @@ binder::Status SurfaceComposerAIDL::removeHdrLayerInfoListener( return binderStatusFromStatusT(status); } -binder::Status SurfaceComposerAIDL::setActivePictureListener( +binder::Status SurfaceComposerAIDL::addActivePictureListener( + const sp<gui::IActivePictureListener>& listener) { + status_t status = checkObservePictureProfilesPermission(); + if (status == OK) { + mFlinger->addActivePictureListener(listener); + } + return binderStatusFromStatusT(status); +} + +binder::Status SurfaceComposerAIDL::removeActivePictureListener( const sp<gui::IActivePictureListener>& listener) { status_t status = checkObservePictureProfilesPermission(); if (status == OK) { - mFlinger->setActivePictureListener(listener); + mFlinger->removeActivePictureListener(listener); } return binderStatusFromStatusT(status); } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index cdd83f2149..3f454ba1b8 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -69,13 +69,13 @@ #include <ui/FenceResult.h> #include <common/FlagManager.h> -#include "ActivePictureUpdater.h" -#include "BackgroundExecutor.h" +#include "ActivePictureTracker.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" @@ -87,6 +87,7 @@ #include "LayerVector.h" #include "MutexUtils.h" #include "PowerAdvisor/PowerAdvisor.h" +#include "QueuedTransactionState.h" #include "Scheduler/ISchedulerCallback.h" #include "Scheduler/RefreshRateSelector.h" #include "Scheduler/Scheduler.h" @@ -95,19 +96,15 @@ #include "Tracing/LayerTracing.h" #include "Tracing/TransactionTracing.h" #include "TransactionCallbackInvoker.h" -#include "TransactionState.h" #include "Utils/OnceFuture.h" #include <algorithm> #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; @@ -201,9 +196,6 @@ enum class LatchUnsignaledConfig { Always, }; -struct DisplayRenderAreaBuilder; -struct LayerRenderAreaBuilder; - using DisplayColorSetting = compositionengine::OutputColorSetting; class SurfaceFlinger : public BnSurfaceComposer, @@ -354,9 +346,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 +367,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 +376,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&)>; @@ -667,7 +653,9 @@ private: void updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t connectedLevel, int32_t maxLevel); - void setActivePictureListener(const sp<gui::IActivePictureListener>& listener); + void addActivePictureListener(const sp<gui::IActivePictureListener>& listener); + + void removeActivePictureListener(const sp<gui::IActivePictureListener>& listener); // IBinder::DeathRecipient overrides: void binderDied(const wp<IBinder>& who) override; @@ -730,7 +718,11 @@ private: Fps maxFps); void initiateDisplayModeChanges() REQUIRES(kMainThreadContext) REQUIRES(mStateLock); - void finalizeDisplayModeChange(PhysicalDisplayId) REQUIRES(kMainThreadContext) + + // Returns whether the commit stage should proceed. The return value is ignored when finalizing + // immediate mode changes, which happen toward the end of the commit stage. + // TODO: b/355427258 - Remove the return value once the `synced_resolution_switch` flag is live. + bool finalizeDisplayModeChange(PhysicalDisplayId) REQUIRES(kMainThreadContext) REQUIRES(mStateLock); void dropModeRequest(PhysicalDisplayId) REQUIRES(kMainThreadContext); @@ -797,8 +789,9 @@ private: // For test only bool flushTransactionQueues() REQUIRES(kMainThreadContext); - bool applyTransactions(std::vector<TransactionState>&) REQUIRES(kMainThreadContext); - bool applyAndCommitDisplayTransactionStatesLocked(std::vector<TransactionState>& transactions) + bool applyTransactions(std::vector<QueuedTransactionState>&) REQUIRES(kMainThreadContext); + bool applyAndCommitDisplayTransactionStatesLocked( + std::vector<QueuedTransactionState>& transactions) REQUIRES(kMainThreadContext, mStateLock); // Returns true if there is at least one transaction that needs to be flushed @@ -827,7 +820,7 @@ private: static LatchUnsignaledConfig getLatchUnsignaledConfig(); bool shouldLatchUnsignaled(const layer_state_t&, size_t numStates, bool firstTransaction) const; - bool applyTransactionsLocked(std::vector<TransactionState>& transactions) + bool applyTransactionsLocked(std::vector<QueuedTransactionState>& transactions) REQUIRES(mStateLock, kMainThreadContext); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands) @@ -868,31 +861,77 @@ 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 + std::optional<DisplayId> displayId{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, bool attachGainmap, 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, bool attachGainmap, + ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer, + bool regionSampling, bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener, - std::optional<OutputCompositionState>& displayState, - std::vector<std::pair<Layer*, sp<LayerFE>>>& layers); + 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&, - std::optional<OutputCompositionState>& displayState, - std::vector<std::pair<Layer*, sp<LayerFE>>>& layers); + const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers); void readPersistentProperties(); @@ -1040,6 +1079,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, @@ -1277,7 +1318,7 @@ private: struct HotplugEvent { hal::HWDisplayId hwcDisplayId; - hal::Connection connection = hal::Connection::INVALID; + HWComposer::HotplugEvent event; }; bool mIsHdcpViaNegVsync = false; @@ -1363,6 +1404,7 @@ private: std::atomic<int> mNumTrustedPresentationListeners = 0; std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine; + std::unique_ptr<HWComposer> mHWComposer; CompositionCoveragePerDisplay mCompositionCoverage; @@ -1405,9 +1447,9 @@ private: std::unordered_map<DisplayId, sp<HdrLayerInfoReporter>> mHdrLayerInfoListeners GUARDED_BY(mStateLock); - sp<gui::IActivePictureListener> mActivePictureListener GUARDED_BY(mStateLock); - bool mHaveNewActivePictureListener GUARDED_BY(mStateLock); - ActivePictureUpdater mActivePictureUpdater GUARDED_BY(kMainThreadContext); + ActivePictureTracker mActivePictureTracker GUARDED_BY(kMainThreadContext); + ActivePictureTracker::Listeners mActivePictureListenersToAdd GUARDED_BY(mStateLock); + ActivePictureTracker::Listeners mActivePictureListenersToRemove GUARDED_BY(mStateLock); std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint; @@ -1644,8 +1686,8 @@ public: binder::Status flushJankData(int32_t layerId) override; binder::Status removeJankListener(int32_t layerId, const sp<gui::IJankListener>& listener, int64_t afterVsync) override; - binder::Status setActivePictureListener(const sp<gui::IActivePictureListener>& listener); - binder::Status clearActivePictureListener(); + binder::Status addActivePictureListener(const sp<gui::IActivePictureListener>& listener); + binder::Status removeActivePictureListener(const sp<gui::IActivePictureListener>& listener); private: static const constexpr bool kUsePermissionCache = true; diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp index f39a4d2af4..2676ca6777 100644 --- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp +++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp @@ -20,8 +20,8 @@ #include "FrontEnd/LayerCreationArgs.h" #include "LayerProtoHelper.h" +#include "QueuedTransactionState.h" #include "TransactionProtoParser.h" -#include "TransactionState.h" #include "gui/LayerState.h" namespace android::surfaceflinger { @@ -51,7 +51,8 @@ public: ~FakeExternalTexture() = default; }; -perfetto::protos::TransactionState TransactionProtoParser::toProto(const TransactionState& t) { +perfetto::protos::TransactionState TransactionProtoParser::toProto( + const QueuedTransactionState& t) { perfetto::protos::TransactionState proto; proto.set_pid(t.originPid); proto.set_uid(t.originUid); @@ -300,9 +301,9 @@ perfetto::protos::LayerCreationArgs TransactionProtoParser::toProto(const LayerC return proto; } -TransactionState TransactionProtoParser::fromProto( +QueuedTransactionState TransactionProtoParser::fromProto( const perfetto::protos::TransactionState& proto) { - TransactionState t; + QueuedTransactionState t; t.originPid = proto.pid(); t.originUid = proto.uid(); t.frameTimelineInfo.vsyncId = proto.vsync_id(); diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.h b/services/surfaceflinger/Tracing/TransactionProtoParser.h index b3ab71cfb5..a02e2318ef 100644 --- a/services/surfaceflinger/Tracing/TransactionProtoParser.h +++ b/services/surfaceflinger/Tracing/TransactionProtoParser.h @@ -21,7 +21,7 @@ #include "FrontEnd/DisplayInfo.h" #include "FrontEnd/LayerCreationArgs.h" -#include "TransactionState.h" +#include "QueuedTransactionState.h" namespace android::surfaceflinger { @@ -44,14 +44,14 @@ public: TransactionProtoParser(std::unique_ptr<FlingerDataMapper> provider) : mMapper(std::move(provider)) {} - perfetto::protos::TransactionState toProto(const TransactionState&); + perfetto::protos::TransactionState toProto(const QueuedTransactionState&); perfetto::protos::TransactionState toProto( const std::map<uint32_t /* layerId */, TracingLayerState>&); perfetto::protos::LayerCreationArgs toProto(const LayerCreationArgs& args); perfetto::protos::LayerState toProto(const ResolvedComposerState&); static perfetto::protos::DisplayInfo toProto(const frontend::DisplayInfo&, uint32_t layerStack); - TransactionState fromProto(const perfetto::protos::TransactionState&); + QueuedTransactionState fromProto(const perfetto::protos::TransactionState&); void mergeFromProto(const perfetto::protos::LayerState&, TracingLayerState& outState); void fromProto(const perfetto::protos::LayerCreationArgs&, LayerCreationArgs& outArgs); std::unique_ptr<FlingerDataMapper> mMapper; diff --git a/services/surfaceflinger/Tracing/TransactionTracing.cpp b/services/surfaceflinger/Tracing/TransactionTracing.cpp index bc9f8094f2..1cd75170bf 100644 --- a/services/surfaceflinger/Tracing/TransactionTracing.cpp +++ b/services/surfaceflinger/Tracing/TransactionTracing.cpp @@ -166,7 +166,7 @@ void TransactionTracing::dump(std::string& result) const { mBuffer.dump(result); } -void TransactionTracing::addQueuedTransaction(const TransactionState& transaction) { +void TransactionTracing::addQueuedTransaction(const QueuedTransactionState& transaction) { perfetto::protos::TransactionState* state = new perfetto::protos::TransactionState(mProtoParser.toProto(transaction)); mTransactionQueue.push(state); diff --git a/services/surfaceflinger/Tracing/TransactionTracing.h b/services/surfaceflinger/Tracing/TransactionTracing.h index 7a0fb5ef6e..d784168553 100644 --- a/services/surfaceflinger/Tracing/TransactionTracing.h +++ b/services/surfaceflinger/Tracing/TransactionTracing.h @@ -134,7 +134,7 @@ public: // Flush event from perfetto data source void onFlush(Mode mode); - void addQueuedTransaction(const TransactionState&); + void addQueuedTransaction(const QueuedTransactionState&); void addCommittedTransactions(int64_t vsyncId, nsecs_t commitTime, frontend::Update& update, const frontend::DisplayInfos&, bool displayInfoChanged); status_t writeToFile(const std::string& filename = FILE_PATH); diff --git a/services/surfaceflinger/Tracing/tools/Android.bp b/services/surfaceflinger/Tracing/tools/Android.bp index 63c1b37166..d2ffcc0f73 100644 --- a/services/surfaceflinger/Tracing/tools/Android.bp +++ b/services/surfaceflinger/Tracing/tools/Android.bp @@ -27,6 +27,7 @@ cc_binary { defaults: [ "libsurfaceflinger_mocks_defaults", "librenderengine_deps", + "poweradvisor_deps", "surfaceflinger_defaults", "libsurfaceflinger_common_deps", ], diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp index 1dba17585c..5cf42449c0 100644 --- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp +++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp @@ -31,8 +31,8 @@ #include "FrontEnd/LayerCreationArgs.h" #include "FrontEnd/RequestedLayerState.h" #include "LayerProtoHelper.h" +#include "QueuedTransactionState.h" #include "Tracing/LayerTracing.h" -#include "TransactionState.h" #include "cutils/properties.h" #include "LayerTraceGenerator.h" @@ -95,11 +95,11 @@ bool LayerTraceGenerator::generate(const perfetto::protos::TransactionTraceFile& addedLayers.emplace_back(std::make_unique<frontend::RequestedLayerState>(args)); } - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.reserve((size_t)entry.transactions_size()); for (int j = 0; j < entry.transactions_size(); j++) { // apply transactions - TransactionState transaction = parser.fromProto(entry.transactions(j)); + 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( diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp index 5e78426c77..abde524214 100644 --- a/services/surfaceflinger/common/FlagManager.cpp +++ b/services/surfaceflinger/common/FlagManager.cpp @@ -104,68 +104,84 @@ 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); /// Trunk stable server (R/W) flags /// - DUMP_ACONFIG_FLAG(refresh_rate_overlay_on_external_display); DUMP_ACONFIG_FLAG(adpf_gpu_sf); DUMP_ACONFIG_FLAG(adpf_native_session_manager); DUMP_ACONFIG_FLAG(adpf_use_fmq_channel); 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 + DUMP_ACONFIG_FLAG(add_sf_skipped_frames_to_trace); DUMP_ACONFIG_FLAG(adpf_fmq_sf); + DUMP_ACONFIG_FLAG(allow_n_vsyncs_in_targeter); DUMP_ACONFIG_FLAG(arr_setframerate_gte_enum); - DUMP_ACONFIG_FLAG(connected_display); - DUMP_ACONFIG_FLAG(enable_small_area_detection); - DUMP_ACONFIG_FLAG(stable_edid_ids); - DUMP_ACONFIG_FLAG(frame_rate_category_mrr); - DUMP_ACONFIG_FLAG(misc1); - DUMP_ACONFIG_FLAG(vrr_config); - DUMP_ACONFIG_FLAG(hdcp_level_hal); - DUMP_ACONFIG_FLAG(multithreaded_present); - DUMP_ACONFIG_FLAG(add_sf_skipped_frames_to_trace); - DUMP_ACONFIG_FLAG(use_known_refresh_rate_for_fps_consistency); + DUMP_ACONFIG_FLAG(begone_bright_hlg); DUMP_ACONFIG_FLAG(cache_when_source_crop_layer_only_moved); - DUMP_ACONFIG_FLAG(enable_fro_dependent_features); + 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); + DUMP_ACONFIG_FLAG(deprecate_vsync_sf); + DUMP_ACONFIG_FLAG(detached_mirror); + DUMP_ACONFIG_FLAG(display_config_error_hal); DUMP_ACONFIG_FLAG(display_protected); + DUMP_ACONFIG_FLAG(dont_skip_on_early_ro); + DUMP_ACONFIG_FLAG(enable_fro_dependent_features); + DUMP_ACONFIG_FLAG(enable_layer_command_batching); + DUMP_ACONFIG_FLAG(enable_small_area_detection); + DUMP_ACONFIG_FLAG(filter_frames_before_trace_starts); + DUMP_ACONFIG_FLAG(flush_buffer_slots_to_uncache); + DUMP_ACONFIG_FLAG(force_compile_graphite_renderengine); DUMP_ACONFIG_FLAG(fp16_client_target); + DUMP_ACONFIG_FLAG(frame_rate_category_mrr); DUMP_ACONFIG_FLAG(game_default_frame_rate); - DUMP_ACONFIG_FLAG(enable_layer_command_batching); - DUMP_ACONFIG_FLAG(vulkan_renderengine); - DUMP_ACONFIG_FLAG(renderable_buffer_usage); - DUMP_ACONFIG_FLAG(vrr_bugfix_24q4); - DUMP_ACONFIG_FLAG(vrr_bugfix_dropped_frame); - DUMP_ACONFIG_FLAG(restore_blur_step); - DUMP_ACONFIG_FLAG(dont_skip_on_early_ro); - DUMP_ACONFIG_FLAG(no_vsyncs_on_screen_off); - DUMP_ACONFIG_FLAG(protected_if_client); - DUMP_ACONFIG_FLAG(idle_screen_refresh_rate_timeout); DUMP_ACONFIG_FLAG(graphite_renderengine); - DUMP_ACONFIG_FLAG(filter_frames_before_trace_starts); + DUMP_ACONFIG_FLAG(hdcp_level_hal); + DUMP_ACONFIG_FLAG(idle_screen_refresh_rate_timeout); DUMP_ACONFIG_FLAG(latch_unsignaled_with_auto_refresh_changed); - DUMP_ACONFIG_FLAG(deprecate_vsync_sf); - DUMP_ACONFIG_FLAG(allow_n_vsyncs_in_targeter); - DUMP_ACONFIG_FLAG(detached_mirror); - DUMP_ACONFIG_FLAG(commit_not_composited); - DUMP_ACONFIG_FLAG(correct_dpi_with_display_size); 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(flush_buffer_slots_to_uncache); - DUMP_ACONFIG_FLAG(force_compile_graphite_renderengine); + DUMP_ACONFIG_FLAG(protected_if_client); + DUMP_ACONFIG_FLAG(reject_dupe_layerstacks); + DUMP_ACONFIG_FLAG(renderable_buffer_usage); + 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(display_config_error_hal); - DUMP_ACONFIG_FLAG(connected_display_hdr); - DUMP_ACONFIG_FLAG(deprecate_frame_tracker); - DUMP_ACONFIG_FLAG(skip_invisible_windows_in_input); - DUMP_ACONFIG_FLAG(begone_bright_hlg); + DUMP_ACONFIG_FLAG(use_known_refresh_rate_for_fps_consistency); + DUMP_ACONFIG_FLAG(vrr_bugfix_24q4); + DUMP_ACONFIG_FLAG(vrr_bugfix_dropped_frame); + DUMP_ACONFIG_FLAG(vrr_config); + DUMP_ACONFIG_FLAG(vulkan_renderengine); DUMP_ACONFIG_FLAG(window_blur_kawase2); + /// IMPORTANT - please keep alphabetize to reduce merge conflicts #undef DUMP_ACONFIG_FLAG #undef DUMP_LEGACY_SERVER_FLAG @@ -182,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 { \ @@ -212,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", @@ -266,12 +296,16 @@ FLAG_MANAGER_ACONFIG_FLAG(deprecate_frame_tracker, ""); 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) diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h index d8887f538f..6295c5b17f 100644 --- a/services/surfaceflinger/common/include/common/FlagManager.h +++ b/services/surfaceflinger/common/include/common/FlagManager.h @@ -42,68 +42,82 @@ 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; bool use_skia_tracing() const; /// Trunk stable server (R/W) flags /// - bool refresh_rate_overlay_on_external_display() const; bool adpf_gpu_sf() const; - bool adpf_use_fmq_channel() const; bool adpf_native_session_manager() const; + bool adpf_use_fmq_channel() const; bool adpf_use_fmq_channel_fixed() 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 /// - bool arr_setframerate_gte_enum() const; - bool adpf_fmq_sf() const; - bool connected_display() const; - bool frame_rate_category_mrr() const; - bool enable_small_area_detection() const; - bool stable_edid_ids() const; - bool misc1() const; - bool vrr_config() const; - bool hdcp_level_hal() const; - bool multithreaded_present() const; + /// IMPORTANT - please keep alphabetize to reduce merge conflicts bool add_sf_skipped_frames_to_trace() const; - bool use_known_refresh_rate_for_fps_consistency() const; + bool adpf_fmq_sf() const; + bool allow_n_vsyncs_in_targeter() const; + bool arr_setframerate_gte_enum() const; + bool begone_bright_hlg() const; bool cache_when_source_crop_layer_only_moved() const; - bool enable_fro_dependent_features() 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; + bool deprecate_vsync_sf() const; + bool detached_mirror() const; + bool display_config_error_hal() const; bool display_protected() const; + bool dont_skip_on_early_ro() const; + bool enable_fro_dependent_features() const; + bool enable_layer_command_batching() const; + bool enable_small_area_detection() const; + bool filter_frames_before_trace_starts() const; + bool flush_buffer_slots_to_uncache() const; + bool force_compile_graphite_renderengine() const; bool fp16_client_target() const; + bool frame_rate_category_mrr() const; bool game_default_frame_rate() const; - bool enable_layer_command_batching() const; - bool vulkan_renderengine() const; - bool vrr_bugfix_24q4() const; - bool vrr_bugfix_dropped_frame() const; - bool renderable_buffer_usage() const; - bool restore_blur_step() const; - bool dont_skip_on_early_ro() const; - bool no_vsyncs_on_screen_off() const; - bool protected_if_client() const; - bool idle_screen_refresh_rate_timeout() const; bool graphite_renderengine() const; - bool filter_frames_before_trace_starts() const; + bool hdcp_level_hal() const; + bool idle_screen_refresh_rate_timeout() const; bool latch_unsignaled_with_auto_refresh_changed() const; - bool deprecate_vsync_sf() const; - bool allow_n_vsyncs_in_targeter() const; - bool detached_mirror() const; - bool commit_not_composited() const; - bool correct_dpi_with_display_size() const; 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 flush_buffer_slots_to_uncache() const; - bool force_compile_graphite_renderengine() const; + bool protected_if_client() const; + bool reject_dupe_layerstacks() const; + bool renderable_buffer_usage() const; + 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 display_config_error_hal() const; - bool connected_display_hdr() const; - bool deprecate_frame_tracker() const; - bool skip_invisible_windows_in_input() const; - bool begone_bright_hlg() const; - bool luts_api() const; + bool use_known_refresh_rate_for_fps_consistency() const; + bool vrr_bugfix_24q4() const; + bool vrr_bugfix_dropped_frame() const; + bool vrr_config() const; + bool vulkan_renderengine() const; bool window_blur_kawase2() const; + /// IMPORTANT - please keep alphabetize to reduce merge conflicts protected: // overridden for unit tests 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..73dfa9fa2f 100644 --- a/services/surfaceflinger/main_surfaceflinger.cpp +++ b/services/surfaceflinger/main_surfaceflinger.cpp @@ -132,7 +132,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 +151,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, diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig index bdd826d084..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" @@ -217,6 +224,17 @@ flag { } # no_vsyncs_on_screen_off flag { + name: "reject_dupe_layerstacks" + namespace: "window_surfaces" + description: "Reject duplicate layerstacks for displays" + bug: "370358572" + is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } + } # reject_dupe_layerstacks + +flag { name: "single_hop_screenshot" namespace: "window_surfaces" description: "Only access SF main thread once during a screenshot" @@ -247,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" @@ -296,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/tests/Android.bp b/services/surfaceflinger/tests/Android.bp index 4d5c0fd1de..b5f7a74347 100644 --- a/services/surfaceflinger/tests/Android.bp +++ b/services/surfaceflinger/tests/Android.bp @@ -52,7 +52,7 @@ cc_test { "LayerTypeTransaction_test.cpp", "LayerUpdate_test.cpp", "MirrorLayer_test.cpp", - "MultiDisplayLayerBounds_test.cpp", + "MultiDisplay_test.cpp", "RefreshRateOverlay_test.cpp", "RelativeZ_test.cpp", "ReleaseBufferCallback_test.cpp", 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/MultiDisplayLayerBounds_test.cpp b/services/surfaceflinger/tests/MultiDisplay_test.cpp index 65add63165..cf6d3282a1 100644 --- a/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp +++ b/services/surfaceflinger/tests/MultiDisplay_test.cpp @@ -33,7 +33,7 @@ using android::hardware::graphics::common::V1_1::BufferUsage; ::testing::Environment* const binderEnv = ::testing::AddGlobalTestEnvironment(new BinderEnvironment()); -class MultiDisplayLayerBoundsTest : public LayerTransactionTest { +class MultiDisplayTest : public LayerTransactionTest { protected: virtual void SetUp() { LayerTransactionTest::SetUp(); @@ -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 {} @@ -105,7 +105,7 @@ protected: Color mExpectedColor = {63, 63, 195, 255}; }; -TEST_F(MultiDisplayLayerBoundsTest, RenderLayerInVirtualDisplay) { +TEST_F(MultiDisplayTest, RenderLayerInVirtualDisplay) { constexpr ui::LayerStack kLayerStack{1u}; createDisplay(mMainDisplayState.layerStackSpaceRect, kLayerStack); createColorLayer(kLayerStack); @@ -124,7 +124,7 @@ TEST_F(MultiDisplayLayerBoundsTest, RenderLayerInVirtualDisplay) { sc->expectColor(Rect(1, 1, 9, 9), {0, 0, 0, 255}); } -TEST_F(MultiDisplayLayerBoundsTest, RenderLayerInMirroredVirtualDisplay) { +TEST_F(MultiDisplayTest, RenderLayerInMirroredVirtualDisplay) { // Create a display and set its layer stack to the main display's layer stack so // the contents of the main display are mirrored on to the virtual display. @@ -150,7 +150,7 @@ TEST_F(MultiDisplayLayerBoundsTest, RenderLayerInMirroredVirtualDisplay) { sc->expectColor(Rect(0, 0, 9, 9), {0, 0, 0, 255}); } -TEST_F(MultiDisplayLayerBoundsTest, RenderLayerWithPromisedFenceInMirroredVirtualDisplay) { +TEST_F(MultiDisplayTest, RenderLayerWithPromisedFenceInMirroredVirtualDisplay) { // Create a display and use a unique layerstack ID for mirrorDisplay() so // the contents of the main display are mirrored on to the virtual display. @@ -181,6 +181,51 @@ TEST_F(MultiDisplayLayerBoundsTest, RenderLayerWithPromisedFenceInMirroredVirtua sc->expectColor(Rect(0, 0, 9, 9), {0, 0, 0, 255}); } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) +TEST_F(MultiDisplayTest, rejectDuplicateLayerStacks) { + if (!FlagManager::getInstance().reject_dupe_layerstacks()) return; + + // Setup + sp<CpuConsumer> cpuConsumer1 = sp<CpuConsumer>::make(static_cast<size_t>(1)); + cpuConsumer1->setName(String8("consumer 1")); + cpuConsumer1->setDefaultBufferSize(100, 100); + sp<IGraphicBufferProducer> cpuProducer1 = + cpuConsumer1->getSurface()->getIGraphicBufferProducer(); + CpuConsumer::LockedBuffer buffer1; + + sp<CpuConsumer> cpuConsumer2 = sp<CpuConsumer>::make(static_cast<size_t>(1)); + cpuConsumer2->setName(String8("consumer 2")); + cpuConsumer2->setDefaultBufferSize(100, 100); + sp<IGraphicBufferProducer> cpuProducer2 = + cpuConsumer2->getSurface()->getIGraphicBufferProducer(); + CpuConsumer::LockedBuffer buffer2; + + SurfaceComposerClient::Transaction t; + constexpr ui::LayerStack layerStack = {123u}; + createColorLayer(layerStack); + + static const std::string kDisplayName1("VirtualDisplay1 - rejectDuplicateLayerStacks"); + sp<IBinder> virtualDisplay1 = + SurfaceComposerClient::createVirtualDisplay(kDisplayName1, false /*isSecure*/); + + t.setDisplaySurface(virtualDisplay1, cpuProducer1); + t.setDisplayLayerStack(virtualDisplay1, layerStack); + t.apply(true); + + static const std::string kDisplayName2("VirtualDisplay2 - rejectDuplicateLayerStacks"); + sp<IBinder> virtualDisplay2 = + SurfaceComposerClient::createVirtualDisplay(kDisplayName2, false /*isSecure*/); + + t.setDisplaySurface(virtualDisplay2, cpuProducer2); + t.setDisplayLayerStack(virtualDisplay2, layerStack); + t.apply(true); + + // The second consumer will not be able to lock a buffer because + // the duplicate layer stack should be rejected. + ASSERT_EQ(NO_ERROR, cpuConsumer1->lockNextBuffer(&buffer1)); + ASSERT_NE(NO_ERROR, cpuConsumer2->lockNextBuffer(&buffer2)); +} +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues 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 7641a45ba4..0925118f87 100644 --- a/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp +++ b/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp @@ -50,7 +50,7 @@ static void updateClientStates(benchmark::State& state) { layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(1)); lifecycleManager.addLayers(std::move(layers)); lifecycleManager.commitChanges(); - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); auto& transactionState = transactions.back().states.front(); @@ -74,7 +74,7 @@ static void updateClientStatesNoChanges(benchmark::State& state) { std::vector<std::unique_ptr<RequestedLayerState>> layers; layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(1)); lifecycleManager.addLayers(std::move(layers)); - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); auto& transactionState = transactions.back().states.front(); diff --git a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h index 97946205ba..7910e775f6 100644 --- a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h +++ b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h @@ -66,8 +66,8 @@ public: /*mirror=*/UNASSIGNED_LAYER_ID)); } - static std::vector<TransactionState> setZTransaction(uint32_t id, int32_t z) { - std::vector<TransactionState> transactions; + static std::vector<QueuedTransactionState> setZTransaction(uint32_t id, int32_t z) { + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -109,8 +109,9 @@ public: mLifecycleManager.addLayers(std::move(layers)); } - std::vector<TransactionState> reparentLayerTransaction(uint32_t id, uint32_t newParentId) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> reparentLayerTransaction(uint32_t id, + uint32_t newParentId) { + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().parentId = newParentId; @@ -124,8 +125,9 @@ public: mLifecycleManager.applyTransactions(reparentLayerTransaction(id, newParentId)); } - std::vector<TransactionState> relativeLayerTransaction(uint32_t id, uint32_t relativeParentId) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> relativeLayerTransaction(uint32_t id, + uint32_t relativeParentId) { + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().relativeParentId = relativeParentId; @@ -139,7 +141,7 @@ public: } void removeRelativeZ(uint32_t id) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eLayerChanged; @@ -148,7 +150,7 @@ public: } void setPosition(uint32_t id, float x, float y) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::ePositionChanged; @@ -167,7 +169,7 @@ public: } void updateBackgroundColor(uint32_t id, half alpha) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged; @@ -183,7 +185,7 @@ public: } void setCrop(uint32_t id, const FloatRect& crop) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -196,7 +198,7 @@ public: void setCrop(uint32_t id, const Rect& crop) { setCrop(id, crop.toFloatRect()); } void setFlags(uint32_t id, uint32_t mask, uint32_t flags) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -208,7 +210,7 @@ public: } void setAlpha(uint32_t id, float alpha) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -219,7 +221,7 @@ public: } void setAutoRefresh(uint32_t id, bool autoRefresh) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -236,7 +238,7 @@ public: void showLayer(uint32_t id) { setFlags(id, layer_state_t::eLayerHidden, 0); } void setColor(uint32_t id, half3 rgb = half3(1._hf, 1._hf, 1._hf)) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eColorChanged; @@ -246,7 +248,7 @@ public: } void setLayerStack(uint32_t id, int32_t layerStack) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -257,7 +259,7 @@ public: } void setTouchableRegion(uint32_t id, Region region) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -272,7 +274,7 @@ public: } void setInputInfo(uint32_t id, std::function<void(gui::WindowInfo&)> configureInput) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -291,7 +293,7 @@ public: void setTouchableRegionCrop(uint32_t id, Region region, uint32_t touchCropId, bool replaceTouchableRegionWithCrop) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -309,7 +311,7 @@ public: } void setBackgroundBlurRadius(uint32_t id, uint32_t backgroundBlurRadius) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -320,7 +322,7 @@ public: } void setFrameRateSelectionPriority(uint32_t id, int32_t priority) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -332,7 +334,7 @@ public: void setFrameRate(uint32_t id, float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -345,7 +347,7 @@ public: } void setFrameRate(uint32_t id, Layer::FrameRate framerate) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -358,7 +360,7 @@ public: } void setFrameRateCategory(uint32_t id, int8_t frameRateCategory) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -369,7 +371,7 @@ public: } void setFrameRateSelectionStrategy(uint32_t id, int8_t strategy) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -381,7 +383,7 @@ public: } void setDefaultFrameRateCompatibility(uint32_t id, int8_t defaultFrameRateCompatibility) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -394,7 +396,7 @@ public: } void setRoundedCorners(uint32_t id, float radius) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -405,7 +407,7 @@ public: } void setBuffer(uint32_t id, std::shared_ptr<renderengine::ExternalTexture> texture) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -438,7 +440,7 @@ public: } void setBufferCrop(uint32_t id, const Rect& bufferCrop) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -449,7 +451,7 @@ public: } void setDamageRegion(uint32_t id, const Region& damageRegion) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -460,7 +462,7 @@ public: } void setDataspace(uint32_t id, ui::Dataspace dataspace) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -473,7 +475,7 @@ public: void setMatrix(uint32_t id, float dsdx, float dtdx, float dtdy, float dsdy) { layer_state_t::matrix22_t matrix{dsdx, dtdx, dtdy, dsdy}; - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -483,8 +485,20 @@ 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<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -495,7 +509,7 @@ public: } void setTrustedOverlay(uint32_t id, gui::TrustedOverlay trustedOverlay) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -506,7 +520,7 @@ public: } void setDropInputMode(uint32_t id, gui::DropInputMode dropInputMode) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); @@ -517,7 +531,7 @@ public: } void setGameMode(uint32_t id, gui::GameMode gameMode) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eMetadataChanged; @@ -529,7 +543,7 @@ public: } void setEdgeExtensionEffect(uint32_t id, int edge) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); diff --git a/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp b/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp new file mode 100644 index 0000000000..8011309519 --- /dev/null +++ b/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp @@ -0,0 +1,482 @@ +/* + * 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 <gmock/gmock.h> +#include <gtest/gtest.h> + +#include <android/gui/ActivePicture.h> +#include <android/gui/IActivePictureListener.h> +#include <compositionengine/mock/CompositionEngine.h> +#include <mock/DisplayHardware/MockComposer.h> +#include <mock/MockLayer.h> +#include <renderengine/mock/RenderEngine.h> + +#include "ActivePictureTracker.h" +#include "LayerFE.h" +#include "TestableSurfaceFlinger.h" + +namespace android { + +using android::compositionengine::LayerFECompositionState; +using android::gui::ActivePicture; +using android::gui::IActivePictureListener; +using android::mock::MockLayer; +using surfaceflinger::frontend::LayerSnapshot; +using testing::_; +using testing::NiceMock; +using testing::Return; +using testing::SizeIs; +using testing::StrictMock; + +class TestableLayerFE : public LayerFE { +public: + TestableLayerFE() : LayerFE("TestableLayerFE"), snapshot(*(new LayerSnapshot)) { + mSnapshot = std::unique_ptr<LayerSnapshot>(&snapshot); + } + + LayerSnapshot& snapshot; +}; + +class MockActivePictureListener : public gui::BnActivePictureListener { +public: + operator ActivePictureTracker::Listeners const() { + return {sp<IActivePictureListener>::fromExisting(this)}; + } + + MOCK_METHOD(binder::Status, onActivePicturesChanged, (const std::vector<ActivePicture>&), + (override)); +}; + +class ActivePictureTrackerTest : public testing::Test { +protected: + const static ActivePictureTracker::Listeners NO_LISTENERS; + + SurfaceFlinger* flinger() { + if (!mFlingerSetup) { + mFlinger.setupMockScheduler(); + mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); + mFlinger.setupRenderEngine(std::make_unique<renderengine::mock::RenderEngine>()); + mFlingerSetup = true; + } + return mFlinger.flinger(); + } + + sp<NiceMock<MockLayer>> createMockLayer(int layerId, int ownerUid) { + auto layer = sp<NiceMock<MockLayer>>::make(flinger(), layerId); + EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(ownerUid))); + return layer; + } + + sp<StrictMock<MockActivePictureListener>> createMockListener() { + return sp<StrictMock<MockActivePictureListener>>::make(); + } + + ActivePictureTracker::Listeners mListenersToAdd; + ActivePictureTracker::Listeners mListenersToRemove; + +private: + TestableSurfaceFlinger mFlinger; + bool mFlingerSetup = false; +}; + +const ActivePictureTracker::Listeners ActivePictureTrackerTest::NO_LISTENERS; + +// Hack to workaround initializer lists not working for parcelables because parcelables inherit from +// Parcelable, which has a virtual destructor. +auto UnorderedElementsAre(std::initializer_list<std::tuple<int32_t, int32_t, int64_t>> tuples) { + std::vector<ActivePicture> activePictures; + for (auto tuple : tuples) { + ActivePicture ap; + ap.layerId = std::get<0>(tuple); + ap.ownerUid = std::get<1>(tuple); + ap.pictureProfileId = std::get<2>(tuple); + activePictures.push_back(ap); + } + return testing::UnorderedElementsAreArray(activePictures); +} + +// Parcelables don't define this for matchers, which is unfortunate +void PrintTo(const ActivePicture& activePicture, std::ostream* os) { + *os << activePicture.toString(); +} + +TEST_F(ActivePictureTrackerTest, whenListenerAdded_called) { + ActivePictureTracker tracker; + auto listener = createMockListener(); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); +} + +TEST_F(ActivePictureTrackerTest, whenListenerAdded_withListenerAlreadyAdded_notCalled) { + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + { + EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenListenerAdded_withUncommittedProfile_calledWithNone) { + auto layer = createMockLayer(100, 10); + TestableLayerFE layerFE; + + ActivePictureTracker tracker; + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } + { + auto listener = createMockListener(); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenListenerAdded_withCommittedProfile_calledWithActivePicture) { + auto layer = createMockLayer(100, 10); + TestableLayerFE layerFE; + + ActivePictureTracker tracker; + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + auto listener = createMockListener(); + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenProfileAdded_calledWithActivePicture) { + auto layer = createMockLayer(100, 10); + TestableLayerFE layerFE; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenContinuesUsingProfile_notCalled) { + auto layer = createMockLayer(100, 10); + TestableLayerFE layerFE; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenProfileIsRemoved_calledWithNoActivePictures) { + auto layer = createMockLayer(100, 10); + TestableLayerFE layerFE; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenProfileIsNotCommitted_calledWithNoActivePictures) { + auto layer = createMockLayer(100, 10); + TestableLayerFE layerFE; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenProfileChanges_calledWithDifferentProfile) { + auto layer = createMockLayer(100, 10); + TestableLayerFE layerFE; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + { + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(2); + layerFE.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 2}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenMultipleCommittedProfiles_calledWithMultipleActivePictures) { + auto layer1 = createMockLayer(100, 10); + TestableLayerFE layerFE1; + + auto layer2 = createMockLayer(200, 20); + TestableLayerFE layerFE2; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE1.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); + + layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); + layerFE2.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(2))) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 20, 2}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenNonCommittedProfileChanges_notCalled) { + auto layer1 = createMockLayer(100, 10); + TestableLayerFE layerFE1; + + auto layer2 = createMockLayer(200, 20); + TestableLayerFE layerFE2; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE1.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); + + layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); + tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + { + layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE1.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); + + layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); + tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenDifferentLayerUsesSameProfile_called) { + auto layer1 = createMockLayer(100, 10); + TestableLayerFE layerFE1; + + auto layer2 = createMockLayer(200, 20); + TestableLayerFE layerFE2; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE1.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); + + layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); + layerFE2.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 20, 2}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + { + layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2); + layerFE1.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); + + layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE2.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 2}, {200, 20, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenSameUidDifferentLayerUsesSameProfile_called) { + auto layer1 = createMockLayer(100, 10); + TestableLayerFE layerFE1; + + auto layer2 = createMockLayer(200, 10); + TestableLayerFE layerFE2; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE1.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); + + layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); + layerFE2.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 10, 2}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + { + layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2); + layerFE1.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); + + layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE2.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 2}, {200, 10, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } +} + +TEST_F(ActivePictureTrackerTest, whenNewLayerUsesSameProfile_called) { + auto layer1 = createMockLayer(100, 10); + TestableLayerFE layerFE1; + + ActivePictureTracker tracker; + auto listener = createMockListener(); + { + layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE1.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); + } + + auto layer2 = createMockLayer(200, 10); + TestableLayerFE layerFE2; + { + layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE1.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); + + layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); + layerFE2.onPictureProfileCommitted(); + tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); + + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 10, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } +} + +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/ActivePictureUpdaterTest.cpp b/services/surfaceflinger/tests/unittests/ActivePictureUpdaterTest.cpp deleted file mode 100644 index b926d2f4da..0000000000 --- a/services/surfaceflinger/tests/unittests/ActivePictureUpdaterTest.cpp +++ /dev/null @@ -1,336 +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 <gmock/gmock.h> -#include <gtest/gtest.h> - -#include <android/gui/ActivePicture.h> -#include <android/gui/IActivePictureListener.h> -#include <compositionengine/mock/CompositionEngine.h> -#include <mock/DisplayHardware/MockComposer.h> -#include <mock/MockLayer.h> -#include <renderengine/mock/RenderEngine.h> - -#include "ActivePictureUpdater.h" -#include "LayerFE.h" -#include "TestableSurfaceFlinger.h" - -namespace android { - -using android::compositionengine::LayerFECompositionState; -using android::gui::ActivePicture; -using android::gui::IActivePictureListener; -using android::mock::MockLayer; -using surfaceflinger::frontend::LayerSnapshot; -using testing::_; -using testing::NiceMock; -using testing::Return; - -class TestableLayerFE : public LayerFE { -public: - TestableLayerFE() : LayerFE("TestableLayerFE"), snapshot(*(new LayerSnapshot)) { - mSnapshot = std::unique_ptr<LayerSnapshot>(&snapshot); - } - - LayerSnapshot& snapshot; -}; - -class ActivePictureUpdaterTest : public testing::Test { -protected: - SurfaceFlinger* flinger() { - if (!mFlingerSetup) { - mFlinger.setupMockScheduler(); - mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); - mFlinger.setupRenderEngine(std::make_unique<renderengine::mock::RenderEngine>()); - mFlingerSetup = true; - } - return mFlinger.flinger(); - } - -private: - TestableSurfaceFlinger mFlinger; - bool mFlingerSetup = false; -}; - -// Hack to workaround initializer lists not working for parcelables because parcelables inherit from -// Parcelable, which has a virtual destructor. -auto UnorderedElementsAre(std::initializer_list<std::tuple<int32_t, int32_t, int64_t>> tuples) { - std::vector<ActivePicture> activePictures; - for (auto tuple : tuples) { - ActivePicture ap; - ap.layerId = std::get<0>(tuple); - ap.ownerUid = std::get<1>(tuple); - ap.pictureProfileId = std::get<2>(tuple); - activePictures.push_back(ap); - } - return testing::UnorderedElementsAreArray(activePictures); -} - -// Parcelables don't define this for matchers, which is unfortunate -void PrintTo(const ActivePicture& activePicture, std::ostream* os) { - *os << activePicture.toString(); -} - -TEST_F(ActivePictureUpdaterTest, notCalledWithNoProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); - TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - ActivePictureUpdater updater; - { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; - updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - - ASSERT_FALSE(updater.updateAndHasChanged()); - } -} - -TEST_F(ActivePictureUpdaterTest, calledWhenLayerStartsUsingProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); - TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - ActivePictureUpdater updater; - { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; - updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - - ASSERT_FALSE(updater.updateAndHasChanged()); - } - { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE.onPictureProfileCommitted(); - updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); - } -} - -TEST_F(ActivePictureUpdaterTest, notCalledWhenLayerContinuesUsingProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); - TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - ActivePictureUpdater updater; - { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE.onPictureProfileCommitted(); - updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); - } - { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE.onPictureProfileCommitted(); - updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - - ASSERT_FALSE(updater.updateAndHasChanged()); - } -} - -TEST_F(ActivePictureUpdaterTest, calledWhenLayerStopsUsingProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); - TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - ActivePictureUpdater updater; - { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE.onPictureProfileCommitted(); - updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); - } - { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; - updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({})); - } -} - -TEST_F(ActivePictureUpdaterTest, calledWhenLayerChangesProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); - TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - ActivePictureUpdater updater; - { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE.onPictureProfileCommitted(); - updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); - } - { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(2); - layerFE.onPictureProfileCommitted(); - updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 2}})); - } -} - -TEST_F(ActivePictureUpdaterTest, notCalledWhenUncommittedLayerChangesProfile) { - sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100); - TestableLayerFE layerFE1; - EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200); - TestableLayerFE layerFE2; - EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(20))); - - ActivePictureUpdater updater; - { - layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE1.onPictureProfileCommitted(); - updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); - - layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); - updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); - } - { - layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE1.onPictureProfileCommitted(); - updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); - - layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); - updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - - ASSERT_FALSE(updater.updateAndHasChanged()); - } -} - -TEST_F(ActivePictureUpdaterTest, calledWhenDifferentLayerUsesSameProfile) { - sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100); - TestableLayerFE layerFE1; - EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200); - TestableLayerFE layerFE2; - EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(20))); - - ActivePictureUpdater updater; - { - layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE1.onPictureProfileCommitted(); - updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); - - layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); - layerFE2.onPictureProfileCommitted(); - updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), - UnorderedElementsAre({{100, 10, 1}, {200, 20, 2}})); - } - { - layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2); - layerFE1.onPictureProfileCommitted(); - updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); - - layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE2.onPictureProfileCommitted(); - updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), - UnorderedElementsAre({{100, 10, 2}, {200, 20, 1}})); - } -} - -TEST_F(ActivePictureUpdaterTest, calledWhenSameUidUsesSameProfile) { - sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100); - TestableLayerFE layerFE1; - EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200); - TestableLayerFE layerFE2; - EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - ActivePictureUpdater updater; - { - layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE1.onPictureProfileCommitted(); - updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); - - layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); - layerFE2.onPictureProfileCommitted(); - updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), - UnorderedElementsAre({{100, 10, 1}, {200, 10, 2}})); - } - { - layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2); - layerFE1.onPictureProfileCommitted(); - updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); - - layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE2.onPictureProfileCommitted(); - updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), - UnorderedElementsAre({{100, 10, 2}, {200, 10, 1}})); - } -} - -TEST_F(ActivePictureUpdaterTest, calledWhenNewLayerUsesSameProfile) { - sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100); - TestableLayerFE layerFE1; - EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - ActivePictureUpdater updater; - { - layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE1.onPictureProfileCommitted(); - updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); - } - - sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200); - TestableLayerFE layerFE2; - EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - - { - layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE1.onPictureProfileCommitted(); - updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); - - layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); - layerFE2.onPictureProfileCommitted(); - updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - - ASSERT_TRUE(updater.updateAndHasChanged()); - EXPECT_THAT(updater.getActivePictures(), - UnorderedElementsAre({{100, 10, 1}, {200, 10, 1}})); - } -} - -} // namespace android diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index 6af51435c3..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", ], } @@ -103,6 +103,7 @@ cc_defaults { "librenderengine_deps", "libsurfaceflinger_common_test_deps", "libsurfaceflinger_proto_deps", + "poweradvisor_deps", ], static_libs: [ "android.hardware.common-V2-ndk", @@ -116,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", @@ -139,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", @@ -156,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/CommitAndCompositeTest.h b/services/surfaceflinger/tests/unittests/CommitAndCompositeTest.h index b517ff02ad..c858d9a477 100644 --- a/services/surfaceflinger/tests/unittests/CommitAndCompositeTest.h +++ b/services/surfaceflinger/tests/unittests/CommitAndCompositeTest.h @@ -54,8 +54,8 @@ struct CommitAndCompositeTest : testing::Test { compositionengine::impl::createDisplay(mFlinger.getCompositionEngine(), std::move(compostionEngineDisplayArgs)); mDisplay = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, - ui::DisplayConnectionType::Internal, HWC_DISPLAY, - kIsPrimary) + ui::DisplayConnectionType::Internal, + DEFAULT_DISPLAY_PORT, HWC_DISPLAY, kIsPrimary) .setDisplaySurface(mDisplaySurface) .setNativeWindow(mNativeWindow) .setPowerMode(hal::PowerMode::ON) @@ -68,7 +68,9 @@ struct CommitAndCompositeTest : testing::Test { using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector; static constexpr hal::HWDisplayId HWC_DISPLAY = FakeHwcDisplayInjector::DEFAULT_HWC_DISPLAY_ID; - static constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u); + static constexpr uint8_t DEFAULT_DISPLAY_PORT = 42u; + static constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = + PhysicalDisplayId::fromPort(DEFAULT_DISPLAY_PORT); static constexpr int DEFAULT_DISPLAY_WIDTH = 1920; static constexpr int DEFAULT_DISPLAY_HEIGHT = 1024; diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 860ad2e013..9ece312850 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" @@ -76,7 +75,8 @@ constexpr hal::HWDisplayId HWC_DISPLAY = FakeHwcDisplayInjector::DEFAULT_HWC_DIS constexpr hal::HWLayerId HWC_LAYER = 5000; constexpr Transform DEFAULT_TRANSFORM = static_cast<Transform>(0); -constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u); +constexpr uint8_t DEFAULT_DISPLAY_PORT = 42u; +constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(DEFAULT_DISPLAY_PORT); constexpr int DEFAULT_DISPLAY_WIDTH = 1920; constexpr int DEFAULT_DISPLAY_HEIGHT = 1024; @@ -198,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(); @@ -276,7 +272,8 @@ struct BaseDisplayVariant { test->mDisplay = FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay, - kDisplayConnectionType, HWC_DISPLAY, kIsPrimary) + kDisplayConnectionType, DEFAULT_DISPLAY_PORT, HWC_DISPLAY, + kIsPrimary) .setDisplaySurface(test->mDisplaySurface) .setNativeWindow(test->mNativeWindow) .setSecure(Derived::IS_SECURE) diff --git a/services/surfaceflinger/tests/unittests/DisplayModeControllerTest.cpp b/services/surfaceflinger/tests/unittests/DisplayModeControllerTest.cpp index 29a1fab5ff..84dc5fc4b7 100644 --- a/services/surfaceflinger/tests/unittests/DisplayModeControllerTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayModeControllerTest.cpp @@ -67,11 +67,12 @@ 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; - mDisplaySnapshotOpt.emplace(mDisplayId, ui::DisplayConnectionType::Internal, + mDisplaySnapshotOpt.emplace(mDisplayId, infoOpt->port, ui::DisplayConnectionType::Internal, makeModes(kMode60, kMode90, kMode120), ui::ColorModes{}, std::nullopt); diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h index fa976c8091..4322af7cef 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); @@ -193,7 +197,7 @@ struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> { } }; -template <uint64_t displayId> +template <VirtualDisplayId::BaseId displayId> struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> { static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); } }; @@ -231,6 +235,16 @@ struct HwcDisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> { static constexpr std::optional<HWDisplayId> value = PhysicalDisplay::HWC_DISPLAY_ID; }; +template <typename> +struct PortGetter { + static constexpr std::optional<uint8_t> value; +}; + +template <typename PhysicalDisplay> +struct PortGetter<PhysicalDisplayIdType<PhysicalDisplay>> { + static constexpr std::optional<uint8_t> value = PhysicalDisplay::PORT; +}; + // DisplayIdType can be: // 1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC. // 2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC. @@ -241,6 +255,7 @@ struct DisplayVariant { using DISPLAY_ID = DisplayIdGetter<DisplayIdType>; using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>; using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>; + using PORT = PortGetter<DisplayIdType>; static constexpr int WIDTH = width; static constexpr int HEIGHT = height; @@ -277,11 +292,13 @@ struct DisplayVariant { TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay, CONNECTION_TYPE::value, + PORT::value, HWC_DISPLAY_ID_OPT::value, static_cast<bool>(PRIMARY)); 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. @@ -348,9 +365,10 @@ 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 @@ -520,13 +538,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 @@ -558,6 +577,11 @@ using OuterDisplayNonSecureVariant = /*hasIdentificationData=*/true, kNonSecure>, 1080, 2092>; +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>, 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/FakeDisplayInjector.h b/services/surfaceflinger/tests/unittests/FakeDisplayInjector.h index 744c53637a..5f7a9f2422 100644 --- a/services/surfaceflinger/tests/unittests/FakeDisplayInjector.h +++ b/services/surfaceflinger/tests/unittests/FakeDisplayInjector.h @@ -24,12 +24,15 @@ namespace android { +static constexpr uint8_t kDefaultPort = 255u; + using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector; using android::adpf::mock::PowerAdvisor; using android::hardware::graphics::composer::hal::HWDisplayId; struct FakeDisplayInjectorArgs { - PhysicalDisplayId displayId = PhysicalDisplayId::fromPort(255u); + PhysicalDisplayId displayId = PhysicalDisplayId::fromPort(kDefaultPort); + uint8_t port = kDefaultPort; HWDisplayId hwcDisplayId = 0; bool isPrimary = true; }; @@ -73,7 +76,7 @@ public: .build()); auto injector = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, - ui::DisplayConnectionType::Internal, + ui::DisplayConnectionType::Internal, args.port, args.hwcDisplayId, args.isPrimary); injector.setNativeWindow(mNativeWindow); 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/LayerHistoryIntegrationTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp index 53a9062a5a..f3d6dccc17 100644 --- a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp @@ -584,7 +584,7 @@ TEST_F(LayerHistoryIntegrationTest, oneLayerExplicitGte_vrr) { auto layer = createLegacyAndFrontedEndLayer(1); showLayer(1); - setFrameRate(1, (33_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE, + setFrameRate(1, (33_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_AT_LEAST, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); setFrameRateCategory(1, 0); @@ -623,7 +623,7 @@ TEST_F(LayerHistoryIntegrationTest, oneLayerExplicitGte_nonVrr) { auto layer = createLegacyAndFrontedEndLayer(1); showLayer(1); - setFrameRate(1, (33_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE, + setFrameRate(1, (33_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_AT_LEAST, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); setFrameRateCategory(1, 0); @@ -662,7 +662,7 @@ TEST_F(LayerHistoryIntegrationTest, oneLayerGteNoVote_arr) { auto layer = createLegacyAndFrontedEndLayer(1); showLayer(1); - setFrameRate(1, (0_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE, + setFrameRate(1, (0_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_AT_LEAST, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); EXPECT_EQ(1u, layerCount()); @@ -694,7 +694,7 @@ TEST_F(LayerHistoryIntegrationTest, oneLayerGteNoVote_mrr) { auto layer = createLegacyAndFrontedEndLayer(1); showLayer(1); - setFrameRate(1, (0_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_GTE, + setFrameRate(1, (0_Hz).getValue(), ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_AT_LEAST, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); setFrameRateCategory(1, 0); diff --git a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp index c7cc21ce07..35ec536d14 100644 --- a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp @@ -21,7 +21,7 @@ #include "FrontEnd/LayerLifecycleManager.h" #include "LayerHierarchyTest.h" -#include "TransactionState.h" +#include "QueuedTransactionState.h" using namespace android::surfaceflinger; @@ -104,7 +104,7 @@ TEST_F(LayerLifecycleManagerTest, updateLayerStates) { EXPECT_FALSE(managedLayers.front()->changes.test(RequestedLayerState::Changes::Z)); // apply transactions that do not affect the hierarchy - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.backgroundBlurRadius = 22; @@ -297,7 +297,7 @@ TEST_F(LayerLifecycleManagerTest, canAddBackgroundLayer) { layers.emplace_back(rootLayer(1)); lifecycleManager.addLayers(std::move(layers)); - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.bgColor.a = 0.5; @@ -326,7 +326,7 @@ TEST_F(LayerLifecycleManagerTest, canDestroyBackgroundLayer) { layers.emplace_back(rootLayer(1)); lifecycleManager.addLayers(std::move(layers)); - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.bgColor.a = 0.5; @@ -360,7 +360,7 @@ TEST_F(LayerLifecycleManagerTest, onParentDestroyDestroysBackgroundLayer) { layers.emplace_back(rootLayer(1)); lifecycleManager.addLayers(std::move(layers)); - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.bgColor.a = 0.5; @@ -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 8c53eef01a..7aad84b545 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, ...) \ ({ \ @@ -329,7 +330,7 @@ TEST_F(LayerSnapshotTest, ReparentingUpdatesGameMode) { } TEST_F(LayerSnapshotTest, UpdateMetadata) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eMetadataChanged; @@ -374,7 +375,7 @@ TEST_F(LayerSnapshotTest, UpdateMetadata) { TEST_F(LayerSnapshotTest, UpdateMetadataOfHiddenLayers) { hideLayer(1); - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eMetadataChanged; @@ -1425,6 +1426,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); @@ -1557,7 +1637,7 @@ TEST_F(LayerSnapshotTest, NonVisibleLayerWithInput) { setColor(3, {-1._hf, -1._hf, -1._hf}); UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged; @@ -1586,7 +1666,7 @@ TEST_F(LayerSnapshotTest, NonVisibleLayerWithInputShouldNotBeIncluded) { setColor(3, {-1._hf, -1._hf, -1._hf}); UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged; @@ -1957,17 +2037,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 @@ -2021,16 +2101,13 @@ TEST_F(LayerSnapshotTest, contentDirtyWhenParentGeometryChanges) { EXPECT_FALSE(getSnapshot(1)->contentDirty); } TEST_F(LayerSnapshotTest, shouldUpdatePictureProfileHandle) { - if (!com_android_graphics_libgui_flags_apply_picture_profiles()) { - GTEST_SKIP() << "Flag disabled, skipping test"; - } - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); - transactions.back().states.front().layerId = 1; - transactions.back().states.front().state.layerId = 1; - transactions.back().states.front().state.what = layer_state_t::ePictureProfileHandleChanged; - transactions.back().states.front().state.pictureProfileHandle = PictureProfileHandle(3); + transactions.back().states.back().layerId = 1; + transactions.back().states.back().state.layerId = 1; + transactions.back().states.back().state.what = layer_state_t::ePictureProfileHandleChanged; + transactions.back().states.back().state.pictureProfileHandle = PictureProfileHandle(3); mLifecycleManager.applyTransactions(transactions); EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Content); @@ -2042,23 +2119,50 @@ TEST_F(LayerSnapshotTest, shouldUpdatePictureProfileHandle) { } TEST_F(LayerSnapshotTest, shouldUpdatePictureProfilePriorityFromAppContentPriority) { - if (!com_android_graphics_libgui_flags_apply_picture_profiles()) { - GTEST_SKIP() << "Flag disabled, skipping test"; + { + std::vector<QueuedTransactionState> transactions; + transactions.emplace_back(); + transactions.back().states.push_back({}); + transactions.back().states.back().layerId = 1; + transactions.back().states.back().state.layerId = 1; + transactions.back().states.back().state.what = layer_state_t::eAppContentPriorityChanged; + transactions.back().states.back().state.appContentPriority = 1; + transactions.back().states.push_back({}); + transactions.back().states.back().layerId = 2; + transactions.back().states.back().state.layerId = 2; + transactions.back().states.back().state.what = layer_state_t::eAppContentPriorityChanged; + transactions.back().states.back().state.appContentPriority = -1; + + mLifecycleManager.applyTransactions(transactions); + EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Content); + + update(mSnapshotBuilder); + + EXPECT_GT(getSnapshot(1)->pictureProfilePriority, getSnapshot(2)->pictureProfilePriority); + EXPECT_EQ(getSnapshot(1)->pictureProfilePriority - getSnapshot(2)->pictureProfilePriority, + 2); + } + { + std::vector<QueuedTransactionState> transactions; + transactions.emplace_back(); + transactions.back().states.push_back({}); + transactions.back().states.back().layerId = 1; + transactions.back().states.back().state.layerId = 1; + transactions.back().states.back().state.what = layer_state_t::eAppContentPriorityChanged; + transactions.back().states.back().state.appContentPriority = INT_MIN; + transactions.back().states.push_back({}); + transactions.back().states.back().layerId = 2; + transactions.back().states.back().state.layerId = 2; + transactions.back().states.back().state.what = layer_state_t::eAppContentPriorityChanged; + transactions.back().states.back().state.appContentPriority = INT_MAX; + + mLifecycleManager.applyTransactions(transactions); + EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Content); + + update(mSnapshotBuilder); + + EXPECT_GT(getSnapshot(2)->pictureProfilePriority, getSnapshot(1)->pictureProfilePriority); } - std::vector<TransactionState> transactions; - transactions.emplace_back(); - transactions.back().states.push_back({}); - transactions.back().states.front().layerId = 1; - transactions.back().states.front().state.layerId = 1; - transactions.back().states.front().state.what = layer_state_t::eAppContentPriorityChanged; - transactions.back().states.front().state.appContentPriority = 3; - - mLifecycleManager.applyTransactions(transactions); - EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Content); - - update(mSnapshotBuilder); - - EXPECT_EQ(getSnapshot(1)->pictureProfilePriority, 3); } } // namespace android::surfaceflinger::frontend 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/SurfaceFlinger_CreateDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp index 2d3ebb47bd..aadff760fe 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()); - + const VirtualDisplayId vid = GpuVirtualDisplayId(baseId); sp<DisplayDevice> device = - mFlinger.createVirtualDisplayDevice(displayToken, *vid, requestedRefreshRate); + mFlinger.createVirtualDisplayDevice(displayToken, vid, requestedRefreshRate); + EXPECT_TRUE(device->isVirtual()); device->adjustRefreshRate(Fps::fromValue(pacesetterDisplayRefreshRate)); // verifying desired value diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp index b0dd5c21f8..62f1a525dc 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp @@ -126,8 +126,9 @@ public: static constexpr HWDisplayId kInnerDisplayHwcId = PrimaryDisplayVariant::HWC_DISPLAY_ID; static constexpr HWDisplayId kOuterDisplayHwcId = kInnerDisplayHwcId + 1; - - static constexpr PhysicalDisplayId kOuterDisplayId = PhysicalDisplayId::fromPort(254u); + static constexpr uint8_t kOuterDisplayPort = 254u; + static constexpr PhysicalDisplayId kOuterDisplayId = + PhysicalDisplayId::fromPort(kOuterDisplayPort); auto injectOuterDisplay() { // For the inner display, this is handled by setupHwcHotplugCallExpectations. @@ -149,6 +150,7 @@ public: kModeId120); }, {.displayId = kOuterDisplayId, + .port = kOuterDisplayPort, .hwcDisplayId = kOuterDisplayHwcId, .isPrimary = kIsPrimary}); @@ -169,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( @@ -324,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, @@ -358,6 +368,44 @@ TEST_F(DisplayModeSwitchingTest, changeResolutionWithoutRefreshRequired) { EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId90_4K)); } +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) { SET_FLAG_FOR_TEST(flags::connected_display, true); diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp index 9bf344c7af..1335640342 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp @@ -163,7 +163,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 +197,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 +219,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); @@ -327,9 +327,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 @@ -378,9 +379,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 diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp index aef467ab9d..b0cda0f270 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) { @@ -59,6 +59,137 @@ TEST_F(HotplugTest, schedulesFrameToCommitDisplayTransaction) { EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded)); } +TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) { + // Configure a primary display with identification data. + using PrimaryDisplay = InnerDisplayVariant; + PrimaryDisplay::setupHwcHotplugCallExpectations(this); + PrimaryDisplay::setupHwcGetActiveConfigCallExpectations(this); + PrimaryDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); + + // TODO: b/241286146 - Remove this unnecessary call. + EXPECT_CALL(*mComposer, + setVsyncEnabled(PrimaryDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) + .WillOnce(Return(Error::NONE)); + + // A single commit should be scheduled. + EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1); + + mFlinger.configure(); + + // Configure an external display with identification info. + using ExternalDisplay = ExternalDisplayWithIdentificationVariant<>; + ExternalDisplay::setupHwcHotplugCallExpectations(this); + ExternalDisplay::setupHwcGetActiveConfigCallExpectations(this); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); + + // TODO: b/241286146 - Remove this unnecessary call. + EXPECT_CALL(*mComposer, + setVsyncEnabled(ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) + .WillOnce(Return(Error::NONE)); + + mFlinger.configure(); + + EXPECT_TRUE(hasPhysicalHwcDisplay(PrimaryDisplay::HWC_DISPLAY_ID)); + EXPECT_TRUE(mFlinger.getHwComposer().isConnected(PrimaryDisplay::DISPLAY_ID::get())); + const auto primaryDisplayIdOpt = + mFlinger.getHwComposer().toPhysicalDisplayId(PrimaryDisplay::HWC_DISPLAY_ID); + ASSERT_TRUE(primaryDisplayIdOpt.has_value()); + const auto primaryPhysicalDisplayOpt = + 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(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 externalDisplayIdOpt = + mFlinger.getHwComposer().toPhysicalDisplayId(ExternalDisplay::HWC_DISPLAY_ID); + ASSERT_TRUE(externalDisplayIdOpt.has_value()); + const auto externalPhysicalDisplayOpt = + 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(ExternalDisplay::PORT::value, externalDisplaySnapshotRef.get().port()); + EXPECT_EQ(ExternalDisplay::CONNECTION_TYPE::value, + externalDisplaySnapshotRef.get().connectionType()); +} + +TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithoutIdentificationData) { + // Configure a primary display without identification data. + using PrimaryDisplay = PrimaryDisplayVariant; + PrimaryDisplay::setupHwcHotplugCallExpectations(this); + PrimaryDisplay::setupHwcGetActiveConfigCallExpectations(this); + PrimaryDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); + + // TODO: b/241286146 - Remove this unnecessary call. + EXPECT_CALL(*mComposer, + setVsyncEnabled(PrimaryDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) + .WillOnce(Return(Error::NONE)); + + // A single commit should be scheduled. + EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1); + + mFlinger.configure(); + + // Configure an external display with identification info. + using ExternalDisplay = ExternalDisplayWithIdentificationVariant<>; + ExternalDisplay::setupHwcHotplugCallExpectations(this); + ExternalDisplay::setupHwcGetActiveConfigCallExpectations(this); + ExternalDisplay::injectPendingHotplugEvent(this, HWComposer::HotplugEvent::Connected); + + // TODO: b/241286146 - Remove this unnecessary call. + EXPECT_CALL(*mComposer, + setVsyncEnabled(ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE)) + .WillOnce(Return(Error::NONE)); + + mFlinger.configure(); + + // Both ID and port are expected to be equal to 0 for primary internal display due to no + // identification data. + constexpr uint8_t primaryInternalDisplayPort = 0u; + 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())); + const auto primaryDisplayIdOpt = + mFlinger.getHwComposer().toPhysicalDisplayId(PrimaryDisplay::HWC_DISPLAY_ID); + ASSERT_TRUE(primaryDisplayIdOpt.has_value()); + const auto primaryPhysicalDisplayOpt = + mFlinger.physicalDisplays().get(primaryDisplayIdOpt.value()); + ASSERT_TRUE(primaryPhysicalDisplayOpt.has_value()); + const auto primaryDisplaySnapshotRef = primaryPhysicalDisplayOpt->get().snapshotRef(); + EXPECT_EQ(primaryInternalDisplayId, primaryDisplaySnapshotRef.get().displayId()); + EXPECT_EQ(primaryInternalDisplayPort, primaryDisplaySnapshotRef.get().port()); + EXPECT_EQ(PrimaryDisplay::CONNECTION_TYPE::value, + primaryDisplaySnapshotRef.get().connectionType()); + + // Even though the external display has identification data available, the lack of data for the + // internal display has set of the legacy multi-display mode in SF and therefore the external + // display's identification data will be ignored. + // Both ID and port are expected to be equal to 1 for external internal display. + constexpr uint8_t externalDisplayPort = 1u; + constexpr PhysicalDisplayId externalDisplayId = + PhysicalDisplayId::fromPort(externalDisplayPort); + EXPECT_TRUE(hasPhysicalHwcDisplay(ExternalDisplay::HWC_DISPLAY_ID)); + EXPECT_TRUE(mFlinger.getHwComposer().isConnected(externalDisplayId)); + const auto externalDisplayIdOpt = + mFlinger.getHwComposer().toPhysicalDisplayId(ExternalDisplay::HWC_DISPLAY_ID); + ASSERT_TRUE(externalDisplayIdOpt.has_value()); + const auto externalPhysicalDisplayOpt = + mFlinger.physicalDisplays().get(externalDisplayIdOpt.value()); + ASSERT_TRUE(externalPhysicalDisplayOpt.has_value()); + const auto externalDisplaySnapshotRef = externalPhysicalDisplayOpt->get().snapshotRef(); + EXPECT_EQ(externalDisplayId, externalDisplaySnapshotRef.get().displayId()); + EXPECT_EQ(externalDisplayPort, externalDisplaySnapshotRef.get().port()); + EXPECT_EQ(ExternalDisplay::CONNECTION_TYPE::value, + externalDisplaySnapshotRef.get().connectionType()); +} + TEST_F(HotplugTest, ignoresDuplicateDisconnection) { // Inject a primary display. PrimaryDisplayVariant::injectHwcDisplay(this); @@ -67,7 +198,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)); @@ -75,15 +206,15 @@ 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 @@ -111,24 +242,73 @@ 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) { + SET_FLAG_FOR_TEST(flags::connected_display, true); + + // 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_SetupNewDisplayDeviceInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp index 352000ef9a..cd554ea1ec 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp @@ -239,7 +239,10 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() { ASSERT_TRUE(displayId); const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value; ASSERT_TRUE(hwcDisplayId); - mFlinger.getHwComposer().allocatePhysicalDisplay(*hwcDisplayId, *displayId, std::nullopt); + const auto port = Case::Display::PORT::value; + ASSERT_TRUE(port); + 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) @@ -250,6 +253,7 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() { state.physical = {.id = *displayId, .hwcDisplayId = *hwcDisplayId, + .port = *port, .activeMode = activeMode}; ui::ColorModes colorModes; @@ -258,7 +262,7 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() { } const auto it = mFlinger.mutablePhysicalDisplays() - .emplace_or_replace(*displayId, displayToken, *displayId, + .emplace_or_replace(*displayId, displayToken, *displayId, *port, *kConnectionTypeOpt, makeModes(activeMode), std::move(colorModes), std::nullopt) .first; @@ -299,6 +303,13 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() { mFlinger.mutableDisplayModeController() .getActiveMode(device->getPhysicalId()) .modePtr->getHwcId()); + + EXPECT_EQ(Case::Display::PORT::value, + mFlinger.physicalDisplays() + .get(device->getPhysicalId()) + .transform([](const display::PhysicalDisplay& display) { + return display.snapshot().port(); + })); } } diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 7f0b7a6585..808445037a 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, @@ -430,11 +429,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) { @@ -461,21 +463,34 @@ public: return mFlinger->setPowerModeInternal(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.displayId = 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) { @@ -514,7 +529,7 @@ public: mergedTransactionIds); } - auto setTransactionStateInternal(TransactionState& transaction) { + auto setTransactionStateInternal(QueuedTransactionState& transaction) { return FTL_FAKE_GUARD(kMainThreadContext, mFlinger->mTransactionHandler.queueTransaction( std::move(transaction))); @@ -771,7 +786,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(); @@ -947,11 +963,13 @@ public: FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger, std::shared_ptr<compositionengine::Display> display, std::optional<ui::DisplayConnectionType> connectionType, + std::optional<uint8_t> port, std::optional<hal::HWDisplayId> hwcDisplayId, bool isPrimary) : mFlinger(flinger), mCreationArgs(flinger.mFlinger, flinger.mFlinger->getHwComposer(), mDisplayToken, display), mConnectionType(connectionType), + mPort(port), mHwcDisplayId(hwcDisplayId) { mCreationArgs.isPrimary = isPrimary; mCreationArgs.initialPowerMode = hal::PowerMode::ON; @@ -1100,11 +1118,12 @@ public: .hwcDisplayId = *mHwcDisplayId, .activeMode = activeModeOpt->get()}; - const auto it = mFlinger.mutablePhysicalDisplays() - .emplace_or_replace(*physicalId, mDisplayToken, *physicalId, - *mConnectionType, std::move(modes), - ui::ColorModes(), std::nullopt) - .first; + const auto it = + mFlinger.mutablePhysicalDisplays() + .emplace_or_replace(*physicalId, mDisplayToken, *physicalId, *mPort, + *mConnectionType, std::move(modes), + ui::ColorModes(), std::nullopt) + .first; mFlinger.mutableDisplayModeController() .registerDisplay(*physicalId, it->second.snapshot(), @@ -1138,6 +1157,7 @@ public: DisplayModeId mActiveModeId; bool mSchedulerRegistration = true; const std::optional<ui::DisplayConnectionType> mConnectionType; + const std::optional<uint8_t> mPort; const std::optional<hal::HWDisplayId> mHwcDisplayId; }; diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp index 1e8cd0a0ca..69dfcc4a8f 100644 --- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp @@ -33,8 +33,8 @@ #include <vector> #include "FrontEnd/TransactionHandler.h" +#include "QueuedTransactionState.h" #include "TestableSurfaceFlinger.h" -#include "TransactionState.h" #include <com_android_graphics_surfaceflinger_flags.h> @@ -84,7 +84,7 @@ public: static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1)); }; - void checkEqual(TransactionInfo info, TransactionState state) { + void checkEqual(TransactionInfo info, QueuedTransactionState state) { EXPECT_EQ(0u, info.states.size()); EXPECT_EQ(0u, state.states.size()); @@ -318,7 +318,7 @@ TEST_F(TransactionApplicationTest, ApplyTokensUseDifferentQueues) { auto applyToken2 = sp<BBinder>::make(); // Transaction 1 has a buffer with an unfired fence. It should not be ready to be applied. - TransactionState transaction1; + QueuedTransactionState transaction1; transaction1.applyToken = applyToken1; transaction1.id = 42069; transaction1.states.emplace_back(); @@ -340,7 +340,7 @@ TEST_F(TransactionApplicationTest, ApplyTokensUseDifferentQueues) { transaction1.isAutoTimestamp = true; // Transaction 2 should be ready to be applied. - TransactionState transaction2; + QueuedTransactionState transaction2; transaction2.applyToken = applyToken2; transaction2.id = 2; transaction2.isAutoTimestamp = true; @@ -446,15 +446,15 @@ public: resolvedStates.emplace_back(resolvedState); } - TransactionState 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(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); mFlinger.setTransactionStateInternal(transactionState); } mFlinger.flushTransactionQueues(); @@ -955,12 +955,12 @@ TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheUnsignaledTheQueue) { TEST(TransactionHandlerTest, QueueTransaction) { TransactionHandler handler; - TransactionState transaction; + QueuedTransactionState transaction; transaction.applyToken = sp<BBinder>::make(); transaction.id = 42; handler.queueTransaction(std::move(transaction)); handler.collectTransactions(); - std::vector<TransactionState> transactionsReadyToBeApplied = handler.flushTransactions(); + std::vector<QueuedTransactionState> transactionsReadyToBeApplied = handler.flushTransactions(); EXPECT_EQ(transactionsReadyToBeApplied.size(), 1u); EXPECT_EQ(transactionsReadyToBeApplied.front().id, 42u); diff --git a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp index af0233063e..d3eec5c6f3 100644 --- a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp @@ -30,7 +30,7 @@ namespace android { TEST(TransactionProtoParserTest, parse) { const sp<IBinder> displayHandle = sp<BBinder>::make(); - TransactionState t1; + QueuedTransactionState t1; t1.originPid = 1; t1.originUid = 2; t1.frameTimelineInfo.vsyncId = 3; @@ -86,7 +86,7 @@ TEST(TransactionProtoParserTest, parse) { TransactionProtoParser parser(std::make_unique<TestMapper>(displayHandle)); perfetto::protos::TransactionState proto = parser.toProto(t1); - TransactionState t2 = parser.fromProto(proto); + QueuedTransactionState t2 = parser.fromProto(proto); ASSERT_EQ(t1.originPid, t2.originPid); ASSERT_EQ(t1.originUid, t2.originUid); diff --git a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp index f8f08c78fd..036d8c414d 100644 --- a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp @@ -49,19 +49,19 @@ protected: void queueAndCommitTransaction(int64_t vsyncId) { frontend::Update update; - TransactionState transaction; + QueuedTransactionState transaction; transaction.id = static_cast<uint64_t>(vsyncId * 3); transaction.originUid = 1; transaction.originPid = 2; mTracing.addQueuedTransaction(transaction); - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; update.transactions.emplace_back(transaction); mTracing.addCommittedTransactions(vsyncId, 0, update, {}, false); flush(); } void verifyEntry(const perfetto::protos::TransactionTraceEntry& actualProto, - const std::vector<TransactionState>& expectedTransactions, + const std::vector<QueuedTransactionState>& expectedTransactions, int64_t expectedVsyncId) { EXPECT_EQ(actualProto.vsync_id(), expectedVsyncId); ASSERT_EQ(actualProto.transactions().size(), @@ -92,10 +92,10 @@ protected: }; TEST_F(TransactionTracingTest, addTransactions) { - std::vector<TransactionState> transactions; + std::vector<QueuedTransactionState> transactions; transactions.reserve(100); for (uint64_t i = 0; i < 100; i++) { - TransactionState transaction; + QueuedTransactionState transaction; transaction.id = i; transaction.originPid = static_cast<int32_t>(i); transaction.mergedTransactionIds = std::vector<uint64_t>{i + 100, i + 102}; @@ -108,13 +108,13 @@ TEST_F(TransactionTracingTest, addTransactions) { int64_t firstTransactionSetVsyncId = 42; frontend::Update firstUpdate; firstUpdate.transactions = - std::vector<TransactionState>(transactions.begin() + 50, transactions.end()); + std::vector<QueuedTransactionState>(transactions.begin() + 50, transactions.end()); mTracing.addCommittedTransactions(firstTransactionSetVsyncId, 0, firstUpdate, {}, false); int64_t secondTransactionSetVsyncId = 43; frontend::Update secondUpdate; secondUpdate.transactions = - std::vector<TransactionState>(transactions.begin(), transactions.begin() + 50); + std::vector<QueuedTransactionState>(transactions.begin(), transactions.begin() + 50); mTracing.addCommittedTransactions(secondTransactionSetVsyncId, 0, secondUpdate, {}, false); flush(); @@ -140,7 +140,7 @@ protected: getLayerCreationArgs(mChildLayerId, mParentLayerId, /*layerIdToMirror=*/UNASSIGNED_LAYER_ID, /*flags=*/456, /*addToRoot=*/true)); - TransactionState transaction; + QueuedTransactionState transaction; transaction.id = 50; ResolvedComposerState layerState; layerState.layerId = mParentLayerId; @@ -164,7 +164,7 @@ protected: // add transactions that modify the layer state further so we can test that layer state // gets merged { - TransactionState transaction; + QueuedTransactionState transaction; transaction.id = 51; ResolvedComposerState layerState; layerState.layerId = mParentLayerId; @@ -278,7 +278,7 @@ protected: /*layerIdToMirror=*/mLayerId, /*flags=*/0, /*addToRoot=*/false)); - TransactionState transaction; + QueuedTransactionState transaction; transaction.id = 50; ResolvedComposerState layerState; layerState.layerId = mLayerId; diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp index 918107d270..a221d5e79b 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; @@ -397,8 +444,8 @@ TEST_F(VSyncPredictorTest, idealModelPredictionsBeforeRegressionModelIsBuilt) { } } -// See b/145667109, and comment in prod code under test. -TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { +TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept_withPredictorRecovery) { + SET_FLAG_FOR_TEST(flags::vsync_predictor_recovery, true); std::vector<nsecs_t> const simulatedVsyncs{ 158929578733000, 158929306806205, // oldest TS in ringbuffer @@ -409,6 +456,34 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { 158929706370359, }; auto const idealPeriod = 11111111; + auto const expectedPeriod = 11079563; + auto const expectedIntercept = 1335662; + + tracker.setDisplayModePtr(displayMode(idealPeriod)); + for (auto const& timestamp : simulatedVsyncs) { + tracker.addVsyncTimestamp(timestamp); + } + + auto [slope, intercept] = tracker.getVSyncPredictionModel(); + EXPECT_THAT(slope, IsCloseTo(expectedPeriod, mMaxRoundingError)); + EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError)); + + // (timePoint - oldestTS) % expectedPeriod works out to be: 894272 + // (timePoint - oldestTS) / expectedPeriod works out to be: 38.08 + auto const timePoint = 158929728723871; + auto const prediction = tracker.nextAnticipatedVSyncTimeFrom(timePoint); + EXPECT_THAT(prediction, Ge(timePoint)); +} + +// See b/145667109, and comment in prod code under test. +TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { + SET_FLAG_FOR_TEST(flags::vsync_predictor_recovery, false); + std::vector<nsecs_t> const simulatedVsyncs{ + 158929578733000, + 158929306806205, // oldest TS in ringbuffer + 158929650879052, 158929661969209, 158929684198847, 158929695268171, 158929706370359, + }; + auto const idealPeriod = 11111111; auto const expectedPeriod = 11113919; auto const expectedIntercept = -1195945; @@ -421,9 +496,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 0d5266e113..7319f1ee22 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -190,6 +190,11 @@ public: MOCK_METHOD(Error, getMaxLayerPictureProfiles, (Display, int32_t*)); MOCK_METHOD(Error, setDisplayPictureProfileId, (Display, PictureProfileId id)); MOCK_METHOD(Error, setLayerPictureProfileId, (Display, Layer, PictureProfileId id)); + 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/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h index ec065a773c..4ca6fe073b 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h @@ -116,6 +116,10 @@ public: MOCK_METHOD(hal::Error, getMaxLayerPictureProfiles, (int32_t*), (override)); MOCK_METHOD(hal::Error, setPictureProfileHandle, (const android::PictureProfileHandle&), (override)); + MOCK_METHOD(hal::Error, getLuts, + (const std::vector<android::sp<android::GraphicBuffer>>&, + std::vector<aidl::android::hardware::graphics::composer3::Luts>*), + (override)); }; class Layer : public HWC2::Layer { diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWComposer.h index 88f83d2e07..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)); @@ -151,6 +152,9 @@ public: MOCK_METHOD(int32_t, getMaxLayerPictureProfiles, (PhysicalDisplayId)); MOCK_METHOD(status_t, setDisplayPictureProfileHandle, (PhysicalDisplayId, const PictureProfileHandle&)); + MOCK_METHOD(status_t, getLuts, + (PhysicalDisplayId, const std::vector<sp<GraphicBuffer>>&, + std::vector<aidl::android::hardware::graphics::composer3::Luts>*)); }; } // namespace android::mock diff --git a/services/surfaceflinger/tests/unittests/mock/PowerAdvisor/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/PowerAdvisor/MockPowerAdvisor.h index 5c4512a2df..5abee16bd0 100644 --- a/services/surfaceflinger/tests/unittests/mock/PowerAdvisor/MockPowerAdvisor.h +++ b/services/surfaceflinger/tests/unittests/mock/PowerAdvisor/MockPowerAdvisor.h @@ -63,6 +63,12 @@ public: MOCK_METHOD(void, setCompositeEnd, (TimePoint compositeEndTime), (override)); MOCK_METHOD(void, setDisplays, (std::vector<DisplayId> & displayIds), (override)); 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/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp index 3ddc4f2aca..536a6b352b 100644 --- a/services/vibratorservice/VibratorHalWrapper.cpp +++ b/services/vibratorservice/VibratorHalWrapper.cpp @@ -131,9 +131,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() { @@ -359,11 +360,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() { diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h index 339a6e1d0d..9a39ad4f7b 100644 --- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h @@ -423,8 +423,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 +511,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; 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/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/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..8c0cce26ba 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 diff --git a/vulkan/vkjson/vkjson.h b/vulkan/vkjson/vkjson.h index 28de680a99..5818c73b16 100644 --- a/vulkan/vkjson/vkjson.h +++ b/vulkan/vkjson/vkjson.h @@ -33,12 +33,6 @@ #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; 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 |