Subject: [PATCH 20/21] drm: activate startup tiled aggregate output

From: Justin Youens <[email-masked]>
Date: Sat, 15 Aug 2026 15:35:43 -0500

---
 src/backend/drm/DRM.cpp                   | 395 ++++++++++++++-
 src/backend/drm/TiledDRMIntegration.cpp   | 585 +++++++++++++++++++++-
 src/backend/drm/TiledDRMIntegration.hpp   |  72 +++
 src/backend/drm/TiledRuntimeAuthority.cpp | 347 ++++++++++++-
 src/backend/drm/TiledRuntimeAuthority.hpp |  82 ++-
 tests/TiledAtomic.cpp                     |  89 +++-
 tests/TiledDRMIntegration.cpp             |   6 +-
 7 files changed, 1541 insertions(+), 35 deletions(-)

diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp
index e00a604d6194fbcde8ddb81f71eadfa0ac7a54a0..39174449a51a74cca3a9660e0725f4bb21f6b850 100644
--- a/src/backend/drm/DRM.cpp
+++ b/src/backend/drm/DRM.cpp
@@ -65,7 +65,10 @@ namespace {
     using Aquamarine::NDRM::NTiledDRMIntegration::eScanStageResult;
     using Aquamarine::NDRM::NTiledRuntimeAuthority::SGroupedTestKMSCapture;
     using Aquamarine::NDRM::NTiledRuntimeAuthority::SGroupedTestLivePlaneCapture;
+    using Aquamarine::NDRM::NTiledRuntimeAuthority::eGroupedFrameFailureReason;
+    using Aquamarine::NDRM::NTiledRuntimeAuthority::eGroupedFrameStatus;
     using Aquamarine::NDRM::NTiledDRMIntegration::SGroupedTestProbeResult;
+    using Aquamarine::NDRM::NTiledDRMIntegration::eGroupedStartupConnectorRole;
     using Aquamarine::NDRM::NTiledAtomic::eTiledReplacementPlaneRole;
     using Aquamarine::NDRM::NTiledScan::SConnectorView;
     using Aquamarine::NDRM::NTiledScan::eScanCompleteness;
@@ -82,6 +85,7 @@ namespace {
 
     thread_local const void* LAST_LEGACY_SCAN_KEY      = nullptr;
     thread_local bool        LAST_LEGACY_SCAN_COMPLETE = false;
+    thread_local bool        TILED_STARTUP_PREPARING   = false;
 
     void                     setLastLegacyScan(const void* key, bool complete) noexcept {
         LAST_LEGACY_SCAN_KEY      = key;
@@ -97,6 +101,11 @@ namespace {
         return VALUE && std::strcmp(VALUE, "1") == 0;
     }
 
+    bool tiledStartupEnabled() noexcept {
+        const auto* const VALUE = std::getenv("AQ_DRM_TILED_STARTUP");
+        return VALUE && std::strcmp(VALUE, "1") == 0;
+    }
+
     void logTiledProbeResult(const CWeakPointer<CBackend>& backend, const std::string& device, const SGroupedTestProbeResult& probe) {
         const auto LOGGER = backend.lock();
         if (!LOGGER || !probe.attempted)
@@ -611,6 +620,153 @@ namespace {
         return capture;
     }
 
+    struct SStartupDisableResourceGraph {
+        SDRMResourcesSnapshot resources;
+        std::vector<uint32_t> planeIds;
+
+        bool                  operator==(const SStartupDisableResourceGraph&) const = default;
+    };
+
+    std::optional<SStartupDisableResourceGraph> captureStartupDisableResourceGraph(const SP<CDRMBackend>& backend, int fd, const std::vector<SP<SDRMConnector>>& connectors,
+                                                                                   const std::vector<SP<SDRMCRTC>>& crtcs, const std::vector<SP<SDRMPlane>>& planes) {
+        if (!backend || fd < 0 || crtcs.empty())
+            return std::nullopt;
+
+        auto* const RESOURCES = drmModeGetResources(fd);
+        if (!RESOURCES)
+            return std::nullopt;
+        CScopeGuard resourcesGuard([RESOURCES] { drmModeFreeResources(RESOURCES); });
+        auto        resources = copyResourcesSnapshot(RESOURCES);
+        if (!resources || !exactResourceOwners(resources->connectors, connectors) || !exactResourceOwners(resources->crtcs, crtcs))
+            return std::nullopt;
+
+        auto* const PLANE_RESOURCES = drmModeGetPlaneResources(fd);
+        if (!PLANE_RESOURCES)
+            return std::nullopt;
+        CScopeGuard planeResourcesGuard([PLANE_RESOURCES] { drmModeFreePlaneResources(PLANE_RESOURCES); });
+        auto        planeIds = copyPlaneResourceIDs(PLANE_RESOURCES);
+        if (!planeIds || !exactResourceOwners(*planeIds, planes))
+            return std::nullopt;
+
+        auto* const LESSEES = drmModeListLessees(fd);
+        if (!LESSEES)
+            return std::nullopt;
+        CScopeGuard lesseesGuard([LESSEES] { drmFree(LESSEES); });
+        if (LESSEES->count != 0)
+            return std::nullopt;
+
+        for (const auto& CONNECTOR : connectors) {
+            if (!CONNECTOR || CONNECTOR->backend.impl_ != backend.impl_ || CONNECTOR->props.values.crtc_id == 0)
+                return std::nullopt;
+            if (CONNECTOR->output) {
+                const auto LEASE = CONNECTOR->output->lease.lock();
+                if (LEASE && LEASE->active)
+                    return std::nullopt;
+            }
+        }
+        for (const auto& CRTC : crtcs) {
+            if (!CRTC || CRTC->backend.impl_ != backend.impl_ || CRTC->props.values.mode_id == 0 || CRTC->props.values.active == 0 || CRTC->pendingFlip.id)
+                return std::nullopt;
+        }
+        for (const auto& PLANE : planes) {
+            if (!PLANE || PLANE->backend.impl_ != backend.impl_ || PLANE->props.values.fb_id == 0 || PLANE->props.values.crtc_id == 0)
+                return std::nullopt;
+        }
+
+        return SStartupDisableResourceGraph{.resources = std::move(*resources), .planeIds = std::move(*planeIds)};
+    }
+
+    bool disableStartupKMSGraph(const SP<CDRMBackend>& backend, int fd, const std::vector<SP<SDRMConnector>>& connectors, const std::vector<SP<SDRMCRTC>>& crtcs,
+                                const std::vector<SP<SDRMPlane>>& planes, uint32_t& failureStage) noexcept {
+        failureStage = 1;
+        try {
+            const auto FIRST = captureStartupDisableResourceGraph(backend, fd, connectors, crtcs, planes);
+            if (!FIRST)
+                return false;
+
+            std::vector<SP<IBuffer>> releaseBuffers;
+            releaseBuffers.reserve((planes.size() * 3) + crtcs.size());
+            const auto REMEMBER_BUFFER = [&releaseBuffers](const SP<CDRMFB>& framebuffer) {
+                const auto BUFFER = framebuffer ? framebuffer->buffer.lock() : SP<IBuffer>{};
+                if (BUFFER && !std::ranges::any_of(releaseBuffers, [&](const auto& existing) { return existing.impl_ == BUFFER.impl_; }))
+                    releaseBuffers.push_back(BUFFER);
+            };
+            for (const auto& PLANE : planes) {
+                REMEMBER_BUFFER(PLANE->front);
+                REMEMBER_BUFFER(PLANE->back);
+                REMEMBER_BUFFER(PLANE->last);
+            }
+            for (const auto& CRTC : crtcs)
+                REMEMBER_BUFFER(CRTC->pendingCursor);
+
+            const auto POPULATE = [&](CDRMAtomicRequest& request) {
+                for (const auto& CONNECTOR : connectors)
+                    request.add(CONNECTOR->id, CONNECTOR->props.values.crtc_id, 0);
+                for (const auto& CRTC : crtcs) {
+                    request.add(CRTC->id, CRTC->props.values.mode_id, 0);
+                    request.add(CRTC->id, CRTC->props.values.active, 0);
+                }
+                for (const auto& PLANE : planes) {
+                    request.add(PLANE->id, PLANE->props.values.fb_id, 0);
+                    request.add(PLANE->id, PLANE->props.values.crtc_id, 0);
+                }
+                return !request.failed;
+            };
+
+            failureStage = 2;
+            {
+                CDRMAtomicRequest testRequest{backend};
+                if (!POPULATE(testRequest) || !testRequest.commit(DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_TEST_ONLY))
+                    return false;
+            }
+
+            failureStage      = 3;
+            const auto SECOND = captureStartupDisableResourceGraph(backend, fd, connectors, crtcs, planes);
+            if (!SECOND || *SECOND != *FIRST)
+                return false;
+
+            failureStage = 4;
+            CDRMAtomicRequest commitRequest{backend};
+            if (!POPULATE(commitRequest) || !commitRequest.commit(DRM_MODE_ATOMIC_ALLOW_MODESET))
+                return false;
+
+            // The blocking commit has made every captured object inactive.
+            // Publish no callback-visible output until all local KMS mirrors
+            // agree with that state and the exact aggregate TEST_ONLY passes.
+            for (const auto& CONNECTOR : connectors) {
+                CONNECTOR->atomic.crtcID = 0;
+                CONNECTOR->cursorEnabled = false;
+                CONNECTOR->refresh       = 0;
+                CONNECTOR->sched.invalidate();
+                if (CONNECTOR->output)
+                    CONNECTOR->output->enabledState = false;
+            }
+            for (const auto& CRTC : crtcs) {
+                if (CRTC->atomic.ownModeID && CRTC->atomic.modeID)
+                    static_cast<void>(drmModeDestroyPropertyBlob(fd, CRTC->atomic.modeID));
+                CRTC->atomic.ownModeID     = false;
+                CRTC->atomic.modeID        = 0;
+                CRTC->atomic.ctmStateKnown = false;
+                CRTC->pendingCursor.reset();
+            }
+            for (const auto& PLANE : planes) {
+                PLANE->front.reset();
+                PLANE->back.reset();
+                PLANE->last.reset();
+            }
+            for (const auto& BUFFER : releaseBuffers) {
+                if (!BUFFER->lockedByBackend)
+                    continue;
+                BUFFER->lockedByBackend = false;
+                try {
+                    BUFFER->events.backendRelease.emit();
+                } catch (...) {}
+            }
+            failureStage = 0;
+            return true;
+        } catch (...) { return false; }
+    }
+
     std::optional<uint64_t> rawConnectorProperty(const drmModeConnector* connector, uint32_t propertyId) {
         if (!connector || propertyId == 0 || connector->count_props < 0 || (connector->count_props > 0 && (!connector->props || !connector->prop_values)))
             return std::nullopt;
@@ -1046,6 +1202,11 @@ void Aquamarine::CDRMBackend::restoreAfterVT() {
     if (!SELF || !PARENT)
         std::terminate();
 
+    if (tiledStartupEnabled() && NDRM::NTiledDRMIntegration::groupedStartupActive(SELF)) {
+        backend->log(AQ_LOG_ERROR, "drm: AQ_DRM_TILED_STARTUP=1 grouped output does not support VT restore; refusing singular restore");
+        return;
+    }
+
     backend->log(AQ_LOG_DEBUG, "drm: Restoring after VT switch");
 
     // Clear stale page-flip bookkeeping for all connectors.
@@ -1671,6 +1832,11 @@ void Aquamarine::CDRMBackend::recheckOutputs() {
     if (!SELF || !PARENT)
         std::terminate();
 
+    if (tiledStartupEnabled() && NDRM::NTiledDRMIntegration::groupedStartupActive(SELF)) {
+        backend->log(AQ_LOG_ERROR, std::format("drm: AQ_DRM_TILED_STARTUP=1 refusing hotplug/rescan on active grouped output {}", gpu->path));
+        return;
+    }
+
     scanConnectors();
     if (!lastLegacyScanComplete(SELF.impl_))
         return;
@@ -1735,15 +1901,28 @@ void Aquamarine::CDRMBackend::recheckOutputs() {
         // recheck, otherwise framebuffer acquisition would fail before a KMS
         // TEST_ONLY request can be built.
         const bool HAS_TEST_ALLOCATOR = (dumbAllocator && dumbAllocator->drmFD() == gpu->fd) || (backend->primaryAllocator && backend->primaryAllocator->drmFD() == gpu->fd);
-        if (!tiledProbeEnabled() || RESULT != eAllocationCaptureResult::INSTALLED || !HAS_TEST_ALLOCATOR)
+        if (RESULT != eAllocationCaptureResult::INSTALLED || !HAS_TEST_ALLOCATOR)
             return;
         uint32_t   captureFailureStage = 0;
-        const auto PROBE               = NDRM::NTiledDRMIntegration::probeCurrentGroupedTestModeset(SELF, [&]() {
+        const auto CAPTURE_PROVIDER    = [&]() {
             auto capture = captureGroupedTestKMS(gpu->fd, connectors, crtcs, planes, captureFailureStage);
             if (!capture)
-                backend->log(AQ_LOG_ERROR, std::format("drm: AQ_DRM_TILED_PROBE=1 live capture failed at stage {}", captureFailureStage));
+                backend->log(AQ_LOG_ERROR, std::format("drm: grouped live capture failed at stage {}", captureFailureStage));
             return capture;
-        });
+        };
+        if (tiledStartupEnabled()) {
+            const auto STARTUP = NDRM::NTiledDRMIntegration::prepareGroupedStartup(SELF, connectors, CAPTURE_PROVIDER);
+            if (STARTUP)
+                backend->log(AQ_LOG_WARNING, std::format("drm: AQ_DRM_TILED_STARTUP=1 PREPARED 5120x2880@60 aggregate on {}", gpu->path));
+            else
+                backend->log(AQ_LOG_ERROR,
+                             std::format("drm: AQ_DRM_TILED_STARTUP=1 FALLBACK ordinary outputs on {} status={} test={} route={}", gpu->path, static_cast<uint32_t>(STARTUP.status),
+                                         static_cast<uint32_t>(STARTUP.test.status), static_cast<uint32_t>(STARTUP.test.routeError)));
+            return;
+        }
+        if (!tiledProbeEnabled())
+            return;
+        const auto PROBE = NDRM::NTiledDRMIntegration::probeCurrentGroupedTestModeset(SELF, [&]() { return CAPTURE_PROVIDER(); });
         logTiledProbeResult(backend, gpu->path, PROBE);
     } catch (...) { return; }
 }
@@ -2228,11 +2407,52 @@ void Aquamarine::CDRMBackend::onReady() {
         }
     }
 
+    // The opt-in startup path first replaces any boot compositor/kernel FBs
+    // with one proven fully inactive graph. Those inherited FB IDs have no
+    // truthful CDRMFB owners, so they cannot enter the exact replacement
+    // builder. Keep both disable requests behind one ordinary KMS exclusion
+    // interval, then rescan synchronously before any newOutput callback.
+    if (tiledStartupEnabled()) {
+        bool                                                 preflight    = false;
+        uint32_t                                             failureStage = 0;
+        NDRM::NTiledRuntimeAuthority::eOrdinaryKMSGateStatus gateStatus   = NDRM::NTiledRuntimeAuthority::eOrdinaryKMSGateStatus::INVALID_INPUT;
+        try {
+            std::vector<NDRM::NTiledRuntimeAuthority::SOrdinaryKMSCRTC> touched;
+            touched.reserve(crtcs.size());
+            for (const auto& CRTC : crtcs)
+                touched.push_back({.owner = CRTC, .id = CRTC ? CRTC->id : 0});
+            const auto GATED = atomic ?
+                NDRM::NTiledDRMIntegration::gateOrdinaryKMS(self, touched, [&] { return disableStartupKMSGraph(self.lock(), gpu->fd, connectors, crtcs, planes, failureStage); }) :
+                NDRM::NTiledRuntimeAuthority::SOrdinaryKMSGateResult{};
+            gateStatus       = GATED.status;
+            preflight        = static_cast<bool>(GATED) && GATED.callbackResult;
+        } catch (...) { preflight = false; }
+
+        if (preflight) {
+            backend->log(AQ_LOG_WARNING, std::format("drm: AQ_DRM_TILED_STARTUP=1 inactive preflight PASS on {}", gpu->path));
+            TILED_STARTUP_PREPARING = true;
+            CScopeGuard startupPreparingGuard([] { TILED_STARTUP_PREPARING = false; });
+            recheckOutputs();
+        } else {
+            backend->log(AQ_LOG_ERROR,
+                         std::format("drm: AQ_DRM_TILED_STARTUP=1 inactive preflight FAIL on {} gate={} stage={}; publishing ordinary outputs", gpu->path,
+                                     static_cast<uint32_t>(gateStatus), failureStage));
+        }
+    }
+
     for (auto const& c : connectors) {
         backend->log(AQ_LOG_DEBUG, std::format("drm: onReady: connector {}", c->id));
         if (!c->output)
             continue;
 
+        const auto STARTUP_ROLE = tiledStartupEnabled() ? NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(self, c) : eGroupedStartupConnectorRole::ORDINARY;
+        if (STARTUP_ROLE == eGroupedStartupConnectorRole::SUPPRESSED) {
+            backend->log(AQ_LOG_WARNING, std::format("drm: AQ_DRM_TILED_STARTUP=1 suppressing ordinary member {}", c->szName));
+            continue;
+        }
+        if (STARTUP_ROLE == eGroupedStartupConnectorRole::TOMBSTONE)
+            continue;
+
         backend->log(AQ_LOG_DEBUG, std::format("drm: onReady: connector {} has output name {}", c->id, c->output->name));
 
         // swapchain has to be created here because allocator is absent in connect if not ready
@@ -2796,6 +3016,12 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
     if (!backend->backend->ready)
         return;
 
+    // onReady's opt-in allocator-backed rescan must not expose either split
+    // member before the exact grouped TEST_ONLY preparation decides whether
+    // publication can proceed.
+    if (TILED_STARTUP_PREPARING)
+        return;
+
     if (!backend->updateSecondaryRendererState()) {
         backend->backend->log(AQ_LOG_ERROR, std::format("drm: Failed to update renderer state for {} on connect", szName));
         return;
@@ -2949,11 +3175,155 @@ bool Aquamarine::CDRMOutput::test() {
 }
 
 void Aquamarine::CDRMOutput::setCursorVisible(bool visible) {
+    if (tiledStartupEnabled() && NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(backend, connector) != eGroupedStartupConnectorRole::ORDINARY)
+        return;
     cursorVisible = visible;
     scheduleFrame(AQ_SCHEDULE_CURSOR_VISIBLE);
 }
 
 bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
+    if (tiledStartupEnabled()) {
+        const auto BACKEND = backend.lock();
+        const auto ROLE    = BACKEND ? NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(BACKEND, connector) : eGroupedStartupConnectorRole::ORDINARY;
+        if (ROLE != eGroupedStartupConnectorRole::ORDINARY) {
+            if (ROLE != eGroupedStartupConnectorRole::PRIMARY || !BACKEND || !BACKEND->backend || !BACKEND->backend->session->active)
+                return false;
+
+            const auto& STATE     = state->state();
+            const auto  MODE      = STATE.customMode ? CSharedPointer<SOutputMode>{} : STATE.mode.lock();
+            uint32_t    SUPPORTED = COutputState::AQ_OUTPUT_STATE_DAMAGE | COutputState::AQ_OUTPUT_STATE_ENABLED | COutputState::AQ_OUTPUT_STATE_PRESENTATION_MODE |
+                COutputState::AQ_OUTPUT_STATE_MODE | COutputState::AQ_OUTPUT_STATE_FORMAT | COutputState::AQ_OUTPUT_STATE_BUFFER;
+            // Match the ordinary atomic path while this startup-only aggregate
+            // advertises implicit synchronization: Hyprland may still commit
+            // its renderer fence, but ordinary Atomic ignores it when
+            // supportsExplicit is false.
+            if (!supportsExplicit)
+                SUPPORTED |= COutputState::AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE;
+            const auto UNSUPPORTED = STATE.committed & ~SUPPORTED;
+            if (!MODE || !STATE.enabled || STATE.presentationMode != AQ_OUTPUT_PRESENTATION_VSYNC || STATE.adaptiveSync || STATE.drmFormat == DRM_FORMAT_INVALID ||
+                UNSUPPORTED != 0 || (STATE.buffer && STATE.buffer->attachments.has<CDRMBufferUnimportable>())) {
+                BACKEND->log(AQ_LOG_ERROR,
+                             std::format("drm: AQ_DRM_TILED_STARTUP=1 rejected unsupported aggregate output state committed=0x{:x} unsupported=0x{:x} enabled={} "
+                                         "presentation={} adaptive={} format=0x{:08x} mode={} customMode={} modeSize={}x{} modeRefresh={} buffer={} inFence={} outFence={} "
+                                         "supportsExplicit={}",
+                                         STATE.committed, UNSUPPORTED, STATE.enabled, static_cast<uint32_t>(STATE.presentationMode), STATE.adaptiveSync, STATE.drmFormat,
+                                         static_cast<bool>(MODE), static_cast<bool>(STATE.customMode), MODE ? MODE->pixelSize.x : 0, MODE ? MODE->pixelSize.y : 0,
+                                         MODE ? MODE->refreshRate : 0, static_cast<bool>(STATE.buffer), STATE.explicitInFence, STATE.explicitOutFence, supportsExplicit));
+                return false;
+            }
+
+            const bool BUFFER_COMMITTED = (STATE.committed & COutputState::AQ_OUTPUT_STATE_BUFFER) != 0;
+            if (!onlyTest && !BUFFER_COMMITTED) {
+                if (!NDRM::NTiledDRMIntegration::groupedStartupStateOnlyCurrent(BACKEND, connector, MODE)) {
+                    BACKEND->log(AQ_LOG_ERROR, std::format("drm: AQ_DRM_TILED_STARTUP=1 state-only {} rejected non-current aggregate committed=0x{:x}", name, STATE.committed));
+                    return false;
+                }
+                events.commit.emit();
+                state->onCommit();
+                lastCommitNoBuffer       = true;
+                needsFrame               = false;
+                connector->commitTainted = false;
+                BACKEND->log(AQ_LOG_DEBUG, std::format("drm: AQ_DRM_TILED_STARTUP=1 state-only {} accepted without KMS", name));
+                return true;
+            }
+
+            CSharedPointer<CDRMFB> framebuffer;
+            SDMABUFAttrs           bufferAttrs;
+            if (STATE.buffer) {
+                if (BACKEND->shouldBlit())
+                    return false;
+                framebuffer = CDRMFB::create(STATE.buffer, BACKEND);
+                if (!framebuffer || framebuffer->dead)
+                    return false;
+                bufferAttrs = STATE.buffer->dmabuf();
+                if (!bufferAttrs.success || bufferAttrs.format != STATE.drmFormat || bufferAttrs.size != MODE->pixelSize)
+                    return false;
+            } else if (!onlyTest) {
+                BACKEND->log(AQ_LOG_ERROR, "drm: AQ_DRM_TILED_STARTUP=1 real aggregate commit requires a buffer");
+                return false;
+            }
+
+            const auto TRANSACTION = onlyTest ? uintptr_t{0} : BACKEND->nextPageFlipID();
+            if (!onlyTest && !TRANSACTION)
+                return false;
+            timespec now{};
+            if (!onlyTest && clock_gettime(CLOCK_MONOTONIC, &now) != 0)
+                return false;
+            const auto NOW_NS   = (static_cast<uint64_t>(now.tv_sec) * 1'000'000'000ULL) + static_cast<uint64_t>(now.tv_nsec);
+            const auto DEADLINE = onlyTest || NOW_NS > std::numeric_limits<uint64_t>::max() - 5'000'000'000ULL ? uint64_t{0} : NOW_NS + 5'000'000'000ULL;
+            if (!onlyTest && !DEADLINE)
+                return false;
+
+            uint32_t   captureFailureStage = 0;
+            const auto RESULT = NDRM::NTiledDRMIntegration::commitGroupedStartup(BACKEND, connector, MODE, framebuffer, STATE.buffer, onlyTest, TRANSACTION, DEADLINE, [&]() {
+                auto capture = captureGroupedTestKMS(BACKEND->gpu->fd, BACKEND->connectors, BACKEND->crtcs, BACKEND->planes, captureFailureStage);
+                if (!capture)
+                    BACKEND->log(AQ_LOG_ERROR, std::format("drm: AQ_DRM_TILED_STARTUP=1 commit capture failed at stage {}", captureFailureStage));
+                return capture;
+            });
+            if (!RESULT.claimed || !RESULT.success) {
+                const bool TRANSIENT_FRAME = !onlyTest && RESULT.claimed && !RESULT.initial && !RESULT.terminalFailure &&
+                    (RESULT.frame.status == eGroupedFrameStatus::RUNTIME_NOT_STARTED ||
+                     (RESULT.frame.status == eGroupedFrameStatus::INVALID_CURRENT && RESULT.frame.failureReason == eGroupedFrameFailureReason::NOT_INVOKED));
+                if (TRANSIENT_FRAME) {
+                    BACKEND->log(AQ_LOG_DEBUG,
+                                 std::format("drm: AQ_DRM_TILED_STARTUP=1 frame {} deferred status={} reason={}", name, static_cast<uint32_t>(RESULT.frame.status),
+                                             static_cast<uint32_t>(RESULT.frame.failureReason)));
+                    return false;
+                }
+                const auto FRAMEBUFFER_BUFFER = framebuffer ? framebuffer->buffer.lock() : CSharedPointer<IBuffer>{};
+                BACKEND->log(
+                    AQ_LOG_ERROR,
+                    std::format("drm: AQ_DRM_TILED_STARTUP=1 {} {} failed claimed={} initial={} terminal={} committed=0x{:x} bufferBit={} bufferImpl={} "
+                                "bufferLocked={} attrs[success={} size={}x{} format=0x{:08x} modifier=0x{:x}] fb[id={} dead={} bufferImpl={} bufferSame={}] "
+                                "initialFrame[status={} route={} request={} stage={} transaction={} "
+                                "effects[built={} prepared={} reserved={} bound={} submit={} kms={} runtime={} registry={} runtimeRollback={} registryRollback={} "
+                                "runtimeRecover={} registryRecover={}]] "
+                                "frame[status={} reason={} route={} resolved={} transaction={} "
+                                "effects[built={} prepared={} reserved={} bound={} submit={} kms={} runtime={} registry={} runtimeRollback={} registryRollback={} "
+                                "runtimeRecover={} registryRecover={}]]",
+                                onlyTest ? "TEST_ONLY" : (RESULT.initial ? "initial" : "frame"), name, RESULT.claimed, RESULT.initial, RESULT.terminalFailure, STATE.committed,
+                                BUFFER_COMMITTED, static_cast<const void*>(STATE.buffer.impl_), STATE.buffer && STATE.buffer->lockedByBackend, bufferAttrs.success,
+                                bufferAttrs.size.x, bufferAttrs.size.y, bufferAttrs.format, bufferAttrs.modifier, framebuffer ? framebuffer->id : 0,
+                                framebuffer && framebuffer->dead, static_cast<const void*>(FRAMEBUFFER_BUFFER.impl_),
+                                FRAMEBUFFER_BUFFER.impl_ != nullptr && FRAMEBUFFER_BUFFER.impl_ == STATE.buffer.impl_, static_cast<uint32_t>(RESULT.initialFrame.status),
+                                static_cast<uint32_t>(RESULT.initialFrame.routeError), static_cast<uint32_t>(RESULT.initialFrame.requestError),
+                                static_cast<uint32_t>(RESULT.initialFrame.stageResult), static_cast<uint32_t>(RESULT.initialFrame.transaction.status),
+                                RESULT.initialFrame.transaction.effects.requestBuilt, RESULT.initialFrame.transaction.effects.runtimePrepared,
+                                RESULT.initialFrame.transaction.effects.reservationReserved, RESULT.initialFrame.transaction.effects.reservationBound,
+                                RESULT.initialFrame.transaction.effects.submitInvoked, RESULT.initialFrame.transaction.effects.kmsAccepted,
+                                RESULT.initialFrame.transaction.effects.runtimeAccepted, RESULT.initialFrame.transaction.effects.registryAccepted,
+                                RESULT.initialFrame.transaction.effects.runtimeRolledBack, RESULT.initialFrame.transaction.effects.registryRolledBack,
+                                RESULT.initialFrame.transaction.effects.runtimeRecovered, RESULT.initialFrame.transaction.effects.registryRecovered,
+                                static_cast<uint32_t>(RESULT.frame.status), static_cast<uint32_t>(RESULT.frame.failureReason), static_cast<uint32_t>(RESULT.frame.routeError),
+                                static_cast<bool>(RESULT.frame.route), static_cast<uint32_t>(RESULT.frame.transaction.status), RESULT.frame.transaction.effects.requestBuilt,
+                                RESULT.frame.transaction.effects.runtimePrepared, RESULT.frame.transaction.effects.reservationReserved,
+                                RESULT.frame.transaction.effects.reservationBound, RESULT.frame.transaction.effects.submitInvoked, RESULT.frame.transaction.effects.kmsAccepted,
+                                RESULT.frame.transaction.effects.runtimeAccepted, RESULT.frame.transaction.effects.registryAccepted,
+                                RESULT.frame.transaction.effects.runtimeRolledBack, RESULT.frame.transaction.effects.registryRolledBack,
+                                RESULT.frame.transaction.effects.runtimeRecovered, RESULT.frame.transaction.effects.registryRecovered));
+                return false;
+            }
+            if (onlyTest)
+                return true;
+
+            const auto& TRANSACTION_RESULT = RESULT.initial ? RESULT.initialFrame.transaction : RESULT.frame.transaction;
+            BACKEND->log(AQ_LOG_DEBUG,
+                         std::format("drm: AQ_DRM_TILED_STARTUP=1 {} {} accepted transaction={} status={} kms={} runtime={} registry={}", RESULT.initial ? "initial" : "frame",
+                                     name, TRANSACTION, static_cast<uint32_t>(TRANSACTION_RESULT.status), TRANSACTION_RESULT.effects.kmsAccepted,
+                                     TRANSACTION_RESULT.effects.runtimeAccepted, TRANSACTION_RESULT.effects.registryAccepted));
+
+            enabledState       = true;
+            connector->refresh = MODE->refreshRate;
+            events.commit.emit();
+            state->onCommit();
+            lastCommitNoBuffer       = false;
+            needsFrame               = false;
+            connector->commitTainted = false;
+            return true;
+        }
+    }
+
     if (!backend->backend->session->active) {
         backend->backend->log(AQ_LOG_ERROR, "drm: Session inactive");
         return false;
@@ -3279,6 +3649,8 @@ SP<IBackendImplementation> Aquamarine::CDRMOutput::getBackend() {
 }
 
 bool Aquamarine::CDRMOutput::setCursor(SP<IBuffer> buffer, const Vector2D& hotspot) {
+    if (tiledStartupEnabled() && NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(backend, connector) != eGroupedStartupConnectorRole::ORDINARY)
+        return false;
     if (!connector->crtc)
         return false;
 
@@ -3375,6 +3747,8 @@ bool Aquamarine::CDRMOutput::setCursor(SP<IBuffer> buffer, const Vector2D& hotsp
 }
 
 void Aquamarine::CDRMOutput::moveCursor(const Vector2D& coord, bool skipSchedule) {
+    if (tiledStartupEnabled() && NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(backend, connector) != eGroupedStartupConnectorRole::ORDINARY)
+        return;
     cursorPos = coord;
     // cursorVisible = true;
     // if (!skipSchedule)
@@ -3427,10 +3801,14 @@ void Aquamarine::CDRMOutput::scheduleFrame(const scheduleFrameReason reason) {
 }
 
 Vector2D Aquamarine::CDRMOutput::cursorPlaneSize() {
+    if (tiledStartupEnabled() && NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(backend, connector) != eGroupedStartupConnectorRole::ORDINARY)
+        return {};
     return backend->drmProps.cursorSize;
 }
 
 size_t Aquamarine::CDRMOutput::getGammaSize() {
+    if (tiledStartupEnabled() && NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(backend, connector) != eGroupedStartupConnectorRole::ORDINARY)
+        return 0;
     if (!backend->atomic) {
         backend->log(AQ_LOG_ERROR, "No support for gamma on the legacy iface");
         return 0;
@@ -3451,6 +3829,8 @@ size_t Aquamarine::CDRMOutput::getGammaSize() {
 }
 
 size_t Aquamarine::CDRMOutput::getDeGammaSize() {
+    if (tiledStartupEnabled() && NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(backend, connector) != eGroupedStartupConnectorRole::ORDINARY)
+        return 0;
     if (!backend->atomic) {
         backend->log(AQ_LOG_ERROR, "No support for gamma on the legacy iface");
         return 0;
@@ -3471,6 +3851,13 @@ size_t Aquamarine::CDRMOutput::getDeGammaSize() {
 }
 
 std::vector<SDRMFormat> Aquamarine::CDRMOutput::getRenderFormats() {
+    if (tiledStartupEnabled()) {
+        const auto ROLE = NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(backend, connector);
+        if (ROLE == eGroupedStartupConnectorRole::PRIMARY)
+            return NDRM::NTiledDRMIntegration::groupedStartupRenderFormats(backend, connector);
+        if (ROLE != eGroupedStartupConnectorRole::ORDINARY)
+            return {};
+    }
     if (!connector->crtc || !connector->crtc->primary || connector->crtc->primary->formats.empty()) {
         backend->log(AQ_LOG_ERROR, "Can't get formats: no crtc");
         return {};
diff --git a/src/backend/drm/TiledDRMIntegration.cpp b/src/backend/drm/TiledDRMIntegration.cpp
index 0220604686f336a534c65d361efd1b0a7b7fd7b8..ac1b9baf20722a46164495179225016fa4157f14 100644
--- a/src/backend/drm/TiledDRMIntegration.cpp
+++ b/src/backend/drm/TiledDRMIntegration.cpp
@@ -1,6 +1,9 @@
 #include "TiledDRMIntegration.hpp"
 
+#include "PlaneFormats.hpp"
+
 #include <algorithm>
+#include <array>
 #include <atomic>
 #include <exception>
 #include <limits>
@@ -101,10 +104,194 @@ namespace {
             return {.status = eOrdinaryKMSGateStatus::EXECUTED, .callbackResult = callback()};
         } catch (...) { return {.status = eOrdinaryKMSGateStatus::CALLBACK_FAILED}; }
     }
+
+    template <typename T, typename U>
+    bool sameOwner(const CSharedPointer<T>& lhs, const CSharedPointer<U>& rhs) noexcept {
+        return lhs.impl_ != nullptr && lhs.impl_ == rhs.impl_;
+    }
+
+    class CGroupedStartupEffectSink final : public IGroupedPublicationEffectSink {
+      public:
+        CGroupedStartupEffectSink(CWeakPointer<CDRMBackend> backend, CSharedPointer<SDRMConnector> primary) noexcept :
+            m_backend(std::move(backend)), m_primary(std::move(primary)) {}
+
+        void frameSubmitted(uintptr_t transactionId) noexcept override {
+            if (!transactionId || !m_primary || !m_primary->output)
+                return;
+            m_submittedTransaction = transactionId;
+            m_primary->sched.onFrameSubmitted();
+        }
+
+        [[nodiscard]] bool frameAccepted(uintptr_t transactionId, const PResolvedTiledAtomicRoute& route, const CSharedPointer<CDRMFB>& framebuffer) noexcept {
+            if (!transactionId || transactionId != m_submittedTransaction || m_pendingRoute || !route || !framebuffer || framebuffer->id != route->framebuffer().id)
+                return false;
+            for (const auto& MEMBER : route->members()) {
+                if (!MEMBER.primaryPlane || MEMBER.primaryPlane->id != MEMBER.primaryPlaneId)
+                    return false;
+            }
+            for (const auto& MEMBER : route->members())
+                MEMBER.primaryPlane->back = framebuffer;
+            m_pendingRoute       = route;
+            m_pendingFramebuffer = framebuffer;
+            return true;
+        }
+
+        void frameCompleted(const PResolvedTiledAtomicRoute& acceptedRoute, const Aquamarine::NDRM::STiledPresentationSample& presentation,
+                            std::span<const CGroupedRuntime::SRelease> releases) noexcept override {
+            const auto BACKEND = m_backend.lock();
+            if (!BACKEND || !m_primary || !m_primary->output || !acceptedRoute || presentation.transactionId == 0 || presentation.transactionId != m_submittedTransaction ||
+                !sameOwner(acceptedRoute, m_pendingRoute) || !m_pendingFramebuffer || m_pendingFramebuffer->id != acceptedRoute->framebuffer().id) {
+                m_terminalFailure = true;
+                if (m_primary)
+                    m_primary->sched.invalidate();
+                return;
+            }
+
+            std::array<CSharedPointer<IBuffer>, 8> releaseBuffers;
+            size_t                                 releaseCount    = 0;
+            const auto                             REMEMBER_BUFFER = [&](const CSharedPointer<IBuffer>& buffer) noexcept {
+                if (!buffer || std::ranges::any_of(std::span{releaseBuffers}.first(releaseCount), [&](const auto& existing) { return sameOwner(existing, buffer); }))
+                    return;
+                if (releaseCount < releaseBuffers.size())
+                    releaseBuffers.at(releaseCount++) = buffer;
+            };
+            const auto REMEMBER_RELEASE = [&](const CSharedPointer<CDRMFB>& fb) noexcept {
+                const auto BUFFER = fb ? fb->buffer.lock() : CSharedPointer<IBuffer>{};
+                REMEMBER_BUFFER(BUFFER);
+            };
+            const bool CACHE_VALID =
+                acceptedRoute->members().size() == 2 && std::ranges::all_of(acceptedRoute->members(), [&](const auto& member) {
+                    return member.primaryPlane && member.primaryPlane->id == member.primaryPlaneId && sameOwner(member.primaryPlane->back, m_pendingFramebuffer);
+                });
+            if (!CACHE_VALID)
+                m_terminalFailure = true;
+            if (CACHE_VALID) {
+                for (const auto& MEMBER : acceptedRoute->members()) {
+                    const auto& PLANE = MEMBER.primaryPlane;
+                    if (PLANE->last && !sameOwner(PLANE->last, PLANE->front) && !sameOwner(PLANE->last, m_pendingFramebuffer))
+                        REMEMBER_RELEASE(PLANE->last);
+                    if (PLANE->front && !sameOwner(PLANE->front, m_pendingFramebuffer))
+                        REMEMBER_RELEASE(PLANE->front);
+                    PLANE->last  = PLANE->front;
+                    PLANE->front = m_pendingFramebuffer;
+                    PLANE->back  = m_pendingFramebuffer;
+                }
+            }
+            for (const auto& RELEASE : releases) {
+                const auto* OWNER = RELEASE.owner.get();
+                if (!OWNER || OWNER->role() != eGroupedFrameOwnerRole::BUFFER || !OWNER->buffer())
+                    continue;
+                const auto& BUFFER = OWNER->buffer();
+                REMEMBER_BUFFER(BUFFER);
+            }
+            m_submittedTransaction = 0;
+            m_pendingRoute.reset();
+            m_pendingFramebuffer.reset();
+            if (CACHE_VALID)
+                m_primary->sched.onFrameComplete();
+            else
+                m_primary->sched.invalidate();
+
+            for (const auto& BUFFER : std::span{releaseBuffers}.first(releaseCount)) {
+                if (!BUFFER->lockedByBackend)
+                    continue;
+                BUFFER->lockedByBackend = false;
+                BUFFER->events.backendRelease.emit();
+            }
+            if (!CACHE_VALID) {
+                BACKEND->log(AQ_LOG_ERROR, "drm: grouped startup plane-cache completion invariant failed");
+                return;
+            }
+
+            CFrameRunningGuard frameRunning(m_primary->sched);
+            timespec           when{
+                .tv_sec  = static_cast<time_t>(presentation.timestampNs / 1'000'000'000ULL),
+                .tv_nsec = static_cast<long>(presentation.timestampNs % 1'000'000'000ULL),
+            };
+            uint32_t flags =
+                IOutput::AQ_OUTPUT_PRESENT_VSYNC | IOutput::AQ_OUTPUT_PRESENT_HW_CLOCK | IOutput::AQ_OUTPUT_PRESENT_HW_COMPLETION | IOutput::AQ_OUTPUT_PRESENT_ZEROCOPY;
+            if (BACKEND->gpuDriver() == AQ_BACKEND_GPU_DRIVER_NVIDIA && presentation.primarySequence == 0)
+                flags &= ~IOutput::AQ_OUTPUT_PRESENT_HW_CLOCK;
+            m_primary->output->events.present.emit(IOutput::SPresentEvent{
+                .presented = BACKEND->sessionActive(),
+                .when      = &when,
+                .seq       = presentation.primarySequence,
+                .refresh =
+                    acceptedRoute->outputMode() && acceptedRoute->outputMode()->refreshRate ? static_cast<int>(1'000'000'000'000LL / acceptedRoute->outputMode()->refreshRate) : 0,
+                .flags = flags,
+            });
+            if (BACKEND->sessionActive() && m_primary->output->enabledState && !m_primary->sched.frameScheduled())
+                m_frameReadyPending = true;
+            try {
+                BACKEND->log(AQ_LOG_DEBUG, "drm: AQ_DRM_TILED_STARTUP=1 grouped frame completed");
+            } catch (...) {}
+        }
+
+        [[nodiscard]] bool deliverPendingFrameReady() noexcept {
+            return deliverPendingFrameReady(
+                [&]() noexcept {
+                    const auto BACKEND = m_backend.lock();
+                    return BACKEND && !m_terminalFailure && m_primary && m_primary->output && BACKEND->sessionActive() && m_primary->output->enabledState &&
+                        !m_primary->sched.frameScheduled();
+                },
+                [&]() { m_primary->sched.frameReady.emit(); });
+        }
+
+        [[nodiscard]] bool terminalFailure() const noexcept {
+            return m_terminalFailure;
+        }
+
+      private:
+        template <typename TReady, typename TCallback>
+        [[nodiscard]] bool deliverPendingFrameReady(TReady&& ready, TCallback&& callback) noexcept {
+            if (!m_frameReadyPending || m_frameReadyDeliveryActive)
+                return false;
+            m_frameReadyPending = false;
+            if (!ready())
+                return false;
+
+            m_frameReadyDeliveryActive = true;
+            Hyprutils::Utils::CScopeGuard deliveryGuard([&] { m_frameReadyDeliveryActive = false; });
+            try {
+                callback();
+                return true;
+            } catch (...) {
+                m_terminalFailure = true;
+                if (m_primary)
+                    m_primary->sched.invalidate();
+                return false;
+            }
+        }
+
+        CWeakPointer<CDRMBackend>     m_backend;
+        CSharedPointer<SDRMConnector> m_primary;
+        uintptr_t                     m_submittedTransaction = 0;
+        PResolvedTiledAtomicRoute     m_pendingRoute;
+        CSharedPointer<CDRMFB>        m_pendingFramebuffer;
+        bool                          m_terminalFailure          = false;
+        bool                          m_frameReadyPending        = false;
+        bool                          m_frameReadyDeliveryActive = false;
+    };
 }
 
 class CTiledDRMIntegrationRegistry::CImpl {
   public:
+    struct SGroupedStartup {
+        POutputBridgeObservation                      observation;
+        PScanGroupDefinition                          group;
+        CSharedPointer<const CModeSet>                modeSet;
+        POutputDefinitionIdentity                     identity;
+        CSharedPointer<SDRMConnector>                 primary;
+        std::vector<CSharedPointer<SDRMConnector>>    members;
+        CSharedPointer<CGroupedStartupEffectSink>     concreteSink;
+        CSharedPointer<IGroupedPublicationEffectSink> sink;
+        PGroupedPublicationInstance                   publication;
+        std::vector<CSharedPointer<SOutputMode>>      ordinaryModes;
+        std::vector<SDRMFormat>                       renderFormats;
+        bool                                          initialAccepted = false;
+        bool                                          terminalFailure = false;
+    };
+
     struct SEntry {
         PBackendLifetime                                            lifetime;
         PDeviceIncarnation                                          device;
@@ -114,6 +301,7 @@ class CTiledDRMIntegrationRegistry::CImpl {
         PAllocationShadow                                           allocationShadow;
         CSharedPointer<COutputBridgeState>                          outputBridge;
         Hyprutils::Memory::CUniquePointer<CGroupedRuntimeAuthority> groupedRuntime;
+        std::optional<SGroupedStartup>                              groupedStartup;
         bool                                                        allocationGateActive      = false;
         bool                                                        groupedTestProbeAttempted = false;
         bool                                                        detachBegun               = false;
@@ -195,6 +383,10 @@ SBeginConnectorScanResult::operator bool() const {
     return static_cast<bool>(scan);
 }
 
+SGroupedStartupPrepareResult::operator bool() const noexcept {
+    return status == eGroupedStartupPrepareStatus::PREPARED;
+}
+
 CAllocationShadow::CAllocationShadow(CSharedPointer<const CPlan> plan) : m_plan(std::move(plan)) {}
 
 const CSharedPointer<const CPlan>& CAllocationShadow::plan() const {
@@ -1080,6 +1272,348 @@ SGroupedTestProbeResult CTiledDRMIntegrationRegistry::probeCurrentGroupedTestMod
     return probeCurrentGroupedTestModesetKey(backend.impl_, captureProvider);
 }
 
+SGroupedStartupPrepareResult CTiledDRMIntegrationRegistry::prepareGroupedStartupKey(const void* key, const CWeakPointer<CDRMBackend>& backend,
+                                                                                    std::span<const CSharedPointer<SDRMConnector>> connectors,
+                                                                                    const TGroupedTestKMSCaptureProvider&          captureProvider) noexcept {
+    const auto THREAD = m_impl->registeredThread(key);
+    if (!THREAD || *THREAD != std::this_thread::get_id())
+        return {.status = eGroupedStartupPrepareStatus::WRONG_THREAD};
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end() || ENTRY->second.detachBegun || !ENTRY->second.outputBridge || !ENTRY->second.groupedRuntime || !ENTRY->second.allocationShadow ||
+        !captureProvider)
+        return {.status = eGroupedStartupPrepareStatus::INVALID_CURRENT};
+    if (ENTRY->second.groupedStartup)
+        return {.status = eGroupedStartupPrepareStatus::PREPARED};
+    if (m_impl->mutationBusy(ENTRY->second))
+        return {.status = eGroupedStartupPrepareStatus::BUSY};
+
+    const auto                   SHADOW = ENTRY->second.allocationShadow;
+    SGroupedStartupPrepareResult result{.status = eGroupedStartupPrepareStatus::INVALID_CURRENT};
+    bool                         allocationCurrent = false;
+    bool                         bridgeCurrent     = false;
+    try {
+        allocationCurrent = withCurrentAllocationKey(key, SHADOW, [&](const CPlan&, const SCurrentState& current) {
+            bridgeCurrent = ENTRY->second.outputBridge->withCurrentOwner(current, [&](const POutputBridgeObservation& observation) {
+                const CGroupProjection* selected = nullptr;
+                for (const auto& candidate : observation->groups()) {
+                    if (candidate.projection() != eGroupProjection::MULTI_STREAM_ALLOCATED || !candidate.scanDefinition() || !candidate.modeSet() ||
+                        !candidate.definitionIdentity() || candidate.scanDefinition()->group().members.size() != 2)
+                        continue;
+                    if (selected) {
+                        result.status = eGroupedStartupPrepareStatus::UNSUPPORTED_TOPOLOGY;
+                        return;
+                    }
+                    selected = &candidate;
+                }
+                if (!selected) {
+                    result.status = eGroupedStartupPrepareStatus::UNSUPPORTED_TOPOLOGY;
+                    return;
+                }
+
+                const auto MODES = selected->modeSet()->modes();
+                auto       mode  = std::ranges::find_if(MODES, [](const auto& binding) {
+                    return binding.outputMode && binding.outputMode->pixelSize.x == 5120.0 && binding.outputMode->pixelSize.y == 2880.0 &&
+                        binding.outputMode->refreshRate >= 59'000 && binding.outputMode->refreshRate <= 61'000 && binding.outputMode->preferred;
+                });
+                if (mode == MODES.end()) {
+                    mode = std::ranges::find_if(MODES, [](const auto& binding) {
+                        return binding.outputMode && binding.outputMode->pixelSize.x == 5120.0 && binding.outputMode->pixelSize.y == 2880.0 &&
+                            binding.outputMode->refreshRate >= 59'000 && binding.outputMode->refreshRate <= 61'000;
+                    });
+                }
+                if (mode == MODES.end() || !mode->outputMode) {
+                    result.status = eGroupedStartupPrepareStatus::UNSUPPORTED_TOPOLOGY;
+                    return;
+                }
+
+                std::map<uint32_t, CSharedPointer<SDRMConnector>> connectorById;
+                for (const auto& CONNECTOR : connectors) {
+                    if (!CONNECTOR || CONNECTOR->id == 0 || CONNECTOR->backend.impl_ != key || !connectorById.emplace(CONNECTOR->id, CONNECTOR).second) {
+                        result.status = eGroupedStartupPrepareStatus::INVALID_CURRENT;
+                        return;
+                    }
+                }
+                std::vector<CSharedPointer<SDRMConnector>> members;
+                members.reserve(selected->scanDefinition()->group().members.size());
+                CSharedPointer<SDRMConnector> primary;
+                for (const auto& MEMBER : selected->scanDefinition()->group().members) {
+                    const auto FOUND = connectorById.find(MEMBER.connectorId);
+                    if (FOUND == connectorById.end() || FOUND->second->status != DRM_MODE_CONNECTED || !FOUND->second->output || !FOUND->second->crtc) {
+                        result.status = eGroupedStartupPrepareStatus::INVALID_CURRENT;
+                        return;
+                    }
+                    members.push_back(FOUND->second);
+                    if (MEMBER.connectorId == selected->scanDefinition()->group().primaryConnector)
+                        primary = FOUND->second;
+                }
+                if (!primary || members.size() != 2) {
+                    result.status = eGroupedStartupPrepareStatus::UNSUPPORTED_TOPOLOGY;
+                    return;
+                }
+
+                std::vector<SPlaneFormatSet> formatSets;
+                size_t                       primaryIndex = members.size();
+                const auto                   ALLOCATION   = selected->allocation();
+                if (!ALLOCATION || ALLOCATION->get().bindings().size() != members.size()) {
+                    result.status = eGroupedStartupPrepareStatus::INVALID_CURRENT;
+                    return;
+                }
+                for (size_t index = 0; index < members.size(); ++index) {
+                    const auto BINDING = std::ranges::find(ALLOCATION->get().bindings(), members.at(index)->id,
+                                                           [](const auto& candidate) { return candidate.connector() ? candidate.connector()->id : 0; });
+                    if (BINDING == ALLOCATION->get().bindings().end() || !BINDING->primaryPlane()) {
+                        result.status = eGroupedStartupPrepareStatus::INVALID_CURRENT;
+                        return;
+                    }
+                    formatSets.push_back({.formats = BINDING->primaryPlane()->formats});
+                    if (sameOwner(members.at(index), primary))
+                        primaryIndex = index;
+                }
+                auto commonFormats = intersectPlaneFormats(formatSets, primaryIndex);
+                if (commonFormats.empty()) {
+                    result.status = eGroupedStartupPrepareStatus::UNSUPPORTED_TOPOLOGY;
+                    return;
+                }
+
+                result.test = ENTRY->second.groupedRuntime->executeCurrentTestProbe(observation, selected->scanDefinition(), mode->outputMode, captureProvider);
+                if (!result.test) {
+                    result.status = eGroupedStartupPrepareStatus::TEST_FAILED;
+                    return;
+                }
+
+                CSharedPointer<CGroupedStartupEffectSink>     concreteSink{new CGroupedStartupEffectSink{backend, primary}};
+                CSharedPointer<IGroupedPublicationEffectSink> sink        = concreteSink;
+                auto                                          publication = CGroupedPublicationInstance::create(selected->definitionIdentity(), sink);
+                if (!sink || !publication) {
+                    result.status = eGroupedStartupPrepareStatus::ALLOCATION_FAILED;
+                    return;
+                }
+                std::vector<CSharedPointer<SOutputMode>> logicalModes;
+                logicalModes.reserve(MODES.size());
+                for (const auto& BINDING : MODES) {
+                    if (!BINDING.outputMode) {
+                        result.status = eGroupedStartupPrepareStatus::INVALID_CURRENT;
+                        return;
+                    }
+                    logicalModes.push_back(BINDING.outputMode);
+                }
+                auto                   ordinaryModes = primary->output->modes;
+                CImpl::SGroupedStartup startup{
+                    .observation   = observation,
+                    .group         = selected->scanDefinition(),
+                    .modeSet       = selected->modeSet(),
+                    .identity      = selected->definitionIdentity(),
+                    .primary       = primary,
+                    .members       = std::move(members),
+                    .concreteSink  = concreteSink,
+                    .sink          = std::move(sink),
+                    .publication   = std::move(publication),
+                    .ordinaryModes = std::move(ordinaryModes),
+                    .renderFormats = std::move(commonFormats),
+                };
+                ENTRY->second.groupedStartup.emplace(std::move(startup));
+                primary->output->modes = std::move(logicalModes);
+                primary->output->state->setMode(mode->outputMode);
+                primary->output->supportsExplicit = false;
+                primary->output->vrrCapable       = false;
+                result.status                     = eGroupedStartupPrepareStatus::PREPARED;
+            });
+        });
+    } catch (...) { return {.status = eGroupedStartupPrepareStatus::ALLOCATION_FAILED}; }
+    if (!allocationCurrent || !bridgeCurrent)
+        return {.status = eGroupedStartupPrepareStatus::INVALID_CURRENT};
+    return result;
+}
+
+SGroupedStartupPrepareResult CTiledDRMIntegrationRegistry::prepareGroupedStartup(const CWeakPointer<CDRMBackend>&               backend,
+                                                                                 std::span<const CSharedPointer<SDRMConnector>> connectors,
+                                                                                 const TGroupedTestKMSCaptureProvider&          captureProvider) noexcept {
+    return prepareGroupedStartupKey(backend.impl_, backend, connectors, captureProvider);
+}
+
+eGroupedStartupConnectorRole CTiledDRMIntegrationRegistry::groupedStartupConnectorRoleKey(const void* key, const CSharedPointer<SDRMConnector>& connector) noexcept {
+    const auto THREAD = m_impl->registeredThread(key);
+    if (!THREAD || *THREAD != std::this_thread::get_id() || !connector)
+        return eGroupedStartupConnectorRole::ORDINARY;
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end() || !ENTRY->second.groupedStartup)
+        return eGroupedStartupConnectorRole::ORDINARY;
+    const auto& STARTUP = *ENTRY->second.groupedStartup;
+    if (sameOwner(STARTUP.primary, connector))
+        return STARTUP.terminalFailure || (STARTUP.concreteSink && STARTUP.concreteSink->terminalFailure()) ? eGroupedStartupConnectorRole::TOMBSTONE :
+                                                                                                              eGroupedStartupConnectorRole::PRIMARY;
+    if (std::ranges::any_of(STARTUP.members, [&](const auto& member) { return sameOwner(member, connector); }))
+        return eGroupedStartupConnectorRole::SUPPRESSED;
+    return eGroupedStartupConnectorRole::ORDINARY;
+}
+
+eGroupedStartupConnectorRole CTiledDRMIntegrationRegistry::groupedStartupConnectorRole(const CWeakPointer<CDRMBackend>&     backend,
+                                                                                       const CSharedPointer<SDRMConnector>& connector) noexcept {
+    return groupedStartupConnectorRoleKey(backend.impl_, connector);
+}
+
+std::vector<SDRMFormat> CTiledDRMIntegrationRegistry::groupedStartupRenderFormatsKey(const void* key, const CSharedPointer<SDRMConnector>& connector) noexcept {
+    if (groupedStartupConnectorRoleKey(key, connector) != eGroupedStartupConnectorRole::PRIMARY)
+        return {};
+    const auto ENTRY = m_impl->entries.find(key);
+    try {
+        return ENTRY == m_impl->entries.end() || !ENTRY->second.groupedStartup ? std::vector<SDRMFormat>{} : ENTRY->second.groupedStartup->renderFormats;
+    } catch (...) { return {}; }
+}
+
+std::vector<SDRMFormat> CTiledDRMIntegrationRegistry::groupedStartupRenderFormats(const CWeakPointer<CDRMBackend>&     backend,
+                                                                                  const CSharedPointer<SDRMConnector>& connector) noexcept {
+    return groupedStartupRenderFormatsKey(backend.impl_, connector);
+}
+
+bool CTiledDRMIntegrationRegistry::groupedStartupStateOnlyCurrentKey(const void* key, const CSharedPointer<SDRMConnector>& connector,
+                                                                     const CSharedPointer<SOutputMode>& outputMode) noexcept {
+    const auto THREAD = m_impl->registeredThread(key);
+    if (!THREAD || *THREAD != std::this_thread::get_id() || !connector || !outputMode)
+        return false;
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end() || !ENTRY->second.groupedStartup || !ENTRY->second.outputBridge || !ENTRY->second.allocationShadow || ENTRY->second.detachBegun ||
+        m_impl->mutationBusy(ENTRY->second))
+        return false;
+    auto& STARTUP = *ENTRY->second.groupedStartup;
+    if (!sameOwner(STARTUP.primary, connector) || STARTUP.terminalFailure || (STARTUP.concreteSink && STARTUP.concreteSink->terminalFailure()) || !STARTUP.modeSet ||
+        !STARTUP.modeSet->logicalModeFor(outputMode))
+        return false;
+
+    const auto SHADOW            = ENTRY->second.allocationShadow;
+    bool       allocationCurrent = false;
+    bool       bridgeCurrent     = false;
+    bool       exactCurrent      = false;
+    try {
+        allocationCurrent = withCurrentAllocationKey(key, SHADOW, [&](const CPlan&, const SCurrentState& current) {
+            bridgeCurrent = ENTRY->second.outputBridge->withCurrentOwner(
+                current, [&](const POutputBridgeObservation& observation) { exactCurrent = sameOwner(observation, STARTUP.observation); });
+        });
+    } catch (...) { return false; }
+    return allocationCurrent && bridgeCurrent && exactCurrent;
+}
+
+bool CTiledDRMIntegrationRegistry::groupedStartupStateOnlyCurrent(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector,
+                                                                  const CSharedPointer<SOutputMode>& outputMode) noexcept {
+    return groupedStartupStateOnlyCurrentKey(backend.impl_, connector, outputMode);
+}
+
+bool CTiledDRMIntegrationRegistry::groupedStartupActive(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    const auto THREAD = m_impl->registeredThread(backend.impl_);
+    if (!THREAD || *THREAD != std::this_thread::get_id())
+        return false;
+    const auto ENTRY = m_impl->entries.find(backend.impl_);
+    return ENTRY != m_impl->entries.end() && ENTRY->second.groupedStartup.has_value();
+}
+
+SGroupedStartupCommitResult CTiledDRMIntegrationRegistry::commitGroupedStartupKey(const void* key, const CWeakPointer<CDRMBackend>& backend,
+                                                                                  const CSharedPointer<SDRMConnector>& connector, const CSharedPointer<SOutputMode>& outputMode,
+                                                                                  const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer, bool onlyTest,
+                                                                                  uintptr_t transactionId, uint64_t deadlineNs,
+                                                                                  const TGroupedTestKMSCaptureProvider& captureProvider) noexcept {
+    SGroupedStartupCommitResult result;
+    const auto                  THREAD = m_impl->registeredThread(key);
+    if (!THREAD || *THREAD != std::this_thread::get_id() || !connector)
+        return result;
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end() || !ENTRY->second.groupedStartup)
+        return result;
+
+    auto& STARTUP = *ENTRY->second.groupedStartup;
+    if (STARTUP.concreteSink && STARTUP.concreteSink->terminalFailure())
+        STARTUP.terminalFailure = true;
+    result.claimed = sameOwner(STARTUP.primary, connector) || std::ranges::any_of(STARTUP.members, [&](const auto& member) { return sameOwner(member, connector); });
+    if (!result.claimed || !sameOwner(STARTUP.primary, connector) || STARTUP.terminalFailure || ENTRY->second.detachBegun || !outputMode || !STARTUP.modeSet ||
+        !STARTUP.modeSet->logicalModeFor(outputMode) || !captureProvider || !ENTRY->second.outputBridge || !ENTRY->second.groupedRuntime || !ENTRY->second.allocationShadow ||
+        m_impl->mutationBusy(ENTRY->second))
+        return result;
+    if ((!framebuffer) != (!buffer) || (!onlyTest && (!framebuffer || !buffer || transactionId == 0 || deadlineNs == 0)))
+        return result;
+
+    const auto SHADOW            = ENTRY->second.allocationShadow;
+    bool       allocationCurrent = false;
+    bool       bridgeCurrent     = false;
+    try {
+        allocationCurrent = withCurrentAllocationKey(key, SHADOW, [&](const CPlan&, const SCurrentState& current) {
+            bridgeCurrent = ENTRY->second.outputBridge->withCurrentOwner(current, [&](const POutputBridgeObservation& observation) {
+                if (!sameOwner(observation, STARTUP.observation))
+                    return;
+
+                if (onlyTest) {
+                    if (!framebuffer) {
+                        result.test = ENTRY->second.groupedRuntime->executeCurrentTestProbe(observation, STARTUP.group, outputMode, captureProvider);
+                    } else {
+                        const auto RESOLVED = ENTRY->second.groupedRuntime->resolveCurrentReplacement(observation, STARTUP.group, outputMode, framebuffer, buffer, captureProvider);
+                        if (!RESOLVED) {
+                            result.test = {.status = eGroupedTestModesetStatus::ROUTE_INVALID, .routeError = RESOLVED.error};
+                            return;
+                        }
+                        result.test = ENTRY->second.groupedRuntime->executeCurrentTestModeset(observation, RESOLVED.replacement, STARTUP.group, outputMode);
+                    }
+                    result.success = static_cast<bool>(result.test);
+                    return;
+                }
+
+                if (!STARTUP.initialAccepted) {
+                    result.initial      = true;
+                    const auto RESOLVED = ENTRY->second.groupedRuntime->resolveCurrentReplacement(observation, STARTUP.group, outputMode, framebuffer, buffer, captureProvider);
+                    if (!RESOLVED) {
+                        result.initialFrame.status     = eGroupedInitialFrameStatus::ROUTE_INVALID;
+                        result.initialFrame.routeError = RESOLVED.error;
+                        return;
+                    }
+                    result.initialFrame = ENTRY->second.groupedRuntime->submitInitialCurrent(observation, RESOLVED.replacement, STARTUP.group, outputMode, STARTUP.publication,
+                                                                                             framebuffer, buffer, transactionId, deadlineNs);
+                    if (result.initialFrame.transaction.effects.kmsAccepted &&
+                        (!STARTUP.concreteSink || !STARTUP.concreteSink->frameAccepted(transactionId, RESOLVED.replacement->targetRoute(), framebuffer))) {
+                        STARTUP.terminalFailure = true;
+                        result.terminalFailure  = true;
+                        return;
+                    }
+                    result.success = static_cast<bool>(result.initialFrame);
+                    if (result.success)
+                        STARTUP.initialAccepted = true;
+                    else if (result.initialFrame.transaction.effects.kmsAccepted) {
+                        STARTUP.terminalFailure = true;
+                        result.terminalFailure  = true;
+                    }
+                    return;
+                }
+
+                result.frame =
+                    ENTRY->second.groupedRuntime->submitFrameCurrent(observation, STARTUP.group, outputMode, STARTUP.publication, framebuffer, buffer, transactionId, deadlineNs);
+                if (result.frame.transaction.effects.kmsAccepted &&
+                    (!STARTUP.concreteSink || !STARTUP.concreteSink->frameAccepted(transactionId, result.frame.route, framebuffer))) {
+                    STARTUP.terminalFailure = true;
+                    result.terminalFailure  = true;
+                    return;
+                }
+                result.success = static_cast<bool>(result.frame);
+                if (!result.success && result.frame.transaction.effects.kmsAccepted) {
+                    STARTUP.terminalFailure = true;
+                    result.terminalFailure  = true;
+                }
+            });
+        });
+    } catch (...) {
+        if ((result.initial && result.initialFrame.transaction.effects.kmsAccepted) || result.frame.transaction.effects.kmsAccepted) {
+            STARTUP.terminalFailure = true;
+            result.terminalFailure  = true;
+        }
+        return result;
+    }
+    if (!allocationCurrent || !bridgeCurrent)
+        result.success = false;
+    return result;
+}
+
+SGroupedStartupCommitResult CTiledDRMIntegrationRegistry::commitGroupedStartup(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector,
+                                                                               const CSharedPointer<SOutputMode>& outputMode, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                               const CSharedPointer<IBuffer>& buffer, bool onlyTest, uintptr_t transactionId, uint64_t deadlineNs,
+                                                                               const TGroupedTestKMSCaptureProvider& captureProvider) noexcept {
+    return commitGroupedStartupKey(backend.impl_, backend, connector, outputMode, framebuffer, buffer, onlyTest, transactionId, deadlineNs, captureProvider);
+}
+
 SGroupedInitialFrameResult CTiledDRMIntegrationRegistry::submitCurrentGroupedInitialFrameKey(const void* key, const POutputBridgeObservation& expected,
                                                                                              const PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
                                                                                              const CSharedPointer<SOutputMode>& outputMode,
@@ -1176,7 +1710,16 @@ SGroupedPageFlipResult CTiledDRMIntegrationRegistry::routeGroupedPageFlipKey(con
         return {};
     if (ENTRY->second.allocationGateActive)
         return {.claimed = ENTRY->second.groupedRuntime->claimsPageFlip(transactionId, crtcId), .disposition = eGroupedPageFlipDisposition::BUSY};
-    return ENTRY->second.groupedRuntime->routePageFlip(transactionId, crtcId, sequence, timestampNs);
+
+    // Completion effects are consumed under CGroupedRuntimeAuthority's
+    // mutation guard. frameReady is synchronous and can immediately submit
+    // the next frame, so deliver it only after routePageFlip() has released
+    // that guard. This matches the ordinary DRM page-flip ordering.
+    const auto SINK   = ENTRY->second.groupedStartup ? ENTRY->second.groupedStartup->concreteSink : CSharedPointer<CGroupedStartupEffectSink>{};
+    auto       result = ENTRY->second.groupedRuntime->routePageFlip(transactionId, crtcId, sequence, timestampNs);
+    if (SINK)
+        static_cast<void>(SINK->deliverPendingFrameReady());
+    return result;
 }
 
 SGroupedPageFlipResult CTiledDRMIntegrationRegistry::routeGroupedPageFlip(const CWeakPointer<CDRMBackend>& backend, uintptr_t transactionId, uint32_t crtcId, uint32_t sequence,
@@ -1333,6 +1876,7 @@ eDetachResult CTiledDRMIntegrationRegistry::terminalizeDetachedKey(const void* k
     if (!ENTRY->second.groupedRuntime || !ENTRY->second.groupedRuntime->terminalShutdown(PROOFS->registry, PROOFS->runtime))
         return eDetachResult::INVALID_STATE;
 
+    ENTRY->second.groupedStartup.reset();
     ENTRY->second.terminalProof = proof;
     return eDetachResult::TERMINALIZED;
 }
@@ -1489,6 +2033,45 @@ SGroupedTestProbeResult Aquamarine::NDRM::NTiledDRMIntegration::probeCurrentGrou
     return REGISTRY ? REGISTRY->probeCurrentGroupedTestModeset(backend, captureProvider) : SGroupedTestProbeResult{};
 }
 
+SGroupedStartupPrepareResult Aquamarine::NDRM::NTiledDRMIntegration::prepareGroupedStartup(const CWeakPointer<CDRMBackend>&               backend,
+                                                                                           std::span<const CSharedPointer<SDRMConnector>> connectors,
+                                                                                           const TGroupedTestKMSCaptureProvider&          captureProvider) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->prepareGroupedStartup(backend, connectors, captureProvider) : SGroupedStartupPrepareResult{};
+}
+
+eGroupedStartupConnectorRole Aquamarine::NDRM::NTiledDRMIntegration::groupedStartupConnectorRole(const CWeakPointer<CDRMBackend>&     backend,
+                                                                                                 const CSharedPointer<SDRMConnector>& connector) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->groupedStartupConnectorRole(backend, connector) : eGroupedStartupConnectorRole::ORDINARY;
+}
+
+std::vector<SDRMFormat> Aquamarine::NDRM::NTiledDRMIntegration::groupedStartupRenderFormats(const CWeakPointer<CDRMBackend>&     backend,
+                                                                                            const CSharedPointer<SDRMConnector>& connector) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->groupedStartupRenderFormats(backend, connector) : std::vector<SDRMFormat>{};
+}
+
+bool Aquamarine::NDRM::NTiledDRMIntegration::groupedStartupStateOnlyCurrent(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector,
+                                                                            const CSharedPointer<SOutputMode>& outputMode) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY && REGISTRY->groupedStartupStateOnlyCurrent(backend, connector, outputMode);
+}
+
+SGroupedStartupCommitResult Aquamarine::NDRM::NTiledDRMIntegration::commitGroupedStartup(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector,
+                                                                                         const CSharedPointer<SOutputMode>& outputMode, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                                         const CSharedPointer<IBuffer>& buffer, bool onlyTest, uintptr_t transactionId,
+                                                                                         uint64_t deadlineNs, const TGroupedTestKMSCaptureProvider& captureProvider) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->commitGroupedStartup(backend, connector, outputMode, framebuffer, buffer, onlyTest, transactionId, deadlineNs, captureProvider) :
+                      SGroupedStartupCommitResult{};
+}
+
+bool Aquamarine::NDRM::NTiledDRMIntegration::groupedStartupActive(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY && REGISTRY->groupedStartupActive(backend);
+}
+
 PAllocationShadow Aquamarine::NDRM::NTiledDRMIntegration::currentAllocationShadow(const CWeakPointer<CDRMBackend>& backend) noexcept {
     auto* const REGISTRY = productionRegistryIfCreated();
     return REGISTRY ? REGISTRY->currentAllocationShadow(backend) : PAllocationShadow{};
diff --git a/src/backend/drm/TiledDRMIntegration.hpp b/src/backend/drm/TiledDRMIntegration.hpp
index 6ab79c76786c9572afb12c9a60a6ca97b8a7537c..7bb8c26c9c38ed6de7e4469586e5d2d25c8ffdb0 100644
--- a/src/backend/drm/TiledDRMIntegration.hpp
+++ b/src/backend/drm/TiledDRMIntegration.hpp
@@ -36,6 +36,7 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
     using NTiledRuntimeAuthority::SOrdinaryKMSGateResult;
     using NTiledRuntimeAuthority::SGroupedPageFlipResult;
     using NTiledRuntimeAuthority::SGroupedInitialFrameResult;
+    using NTiledRuntimeAuthority::SGroupedFrameResult;
     using NTiledRuntimeAuthority::SGroupedTestModesetResult;
     using NTiledRuntimeAuthority::TGroupedTestKMSCaptureProvider;
     using NTiledRuntimeAuthority::PGroupedPublicationInstance;
@@ -61,6 +62,41 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
         SGroupedTestModesetResult test;
     };
 
+    enum class eGroupedStartupPrepareStatus : uint8_t {
+        PREPARED = 0,
+        NOT_ENABLED,
+        WRONG_THREAD,
+        BUSY,
+        INVALID_CURRENT,
+        UNSUPPORTED_TOPOLOGY,
+        TEST_FAILED,
+        ALLOCATION_FAILED,
+    };
+
+    struct AQ_TILED_DRM_PRIVATE SGroupedStartupPrepareResult {
+        eGroupedStartupPrepareStatus status = eGroupedStartupPrepareStatus::INVALID_CURRENT;
+        SGroupedTestModesetResult    test;
+
+        explicit                     operator bool() const noexcept;
+    };
+
+    enum class eGroupedStartupConnectorRole : uint8_t {
+        ORDINARY = 0,
+        PRIMARY,
+        SUPPRESSED,
+        TOMBSTONE,
+    };
+
+    struct AQ_TILED_DRM_PRIVATE SGroupedStartupCommitResult {
+        bool                       claimed         = false;
+        bool                       success         = false;
+        bool                       initial         = false;
+        bool                       terminalFailure = false;
+        SGroupedTestModesetResult  test;
+        SGroupedInitialFrameResult initialFrame;
+        SGroupedFrameResult        frame;
+    };
+
     enum class eScanStageResult : uint8_t {
         PREPARED = 0,
         INCOMPLETE,
@@ -250,6 +286,17 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
                                                                                   const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode) noexcept;
         [[nodiscard]] SGroupedTestProbeResult    probeCurrentGroupedTestModeset(const CWeakPointer<CDRMBackend>&      backend,
                                                                                 const TGroupedTestKMSCaptureProvider& captureProvider) noexcept;
+        [[nodiscard]] SGroupedStartupPrepareResult prepareGroupedStartup(const CWeakPointer<CDRMBackend>& backend, std::span<const CSharedPointer<SDRMConnector>> connectors,
+                                                                         const TGroupedTestKMSCaptureProvider& captureProvider) noexcept;
+        [[nodiscard]] eGroupedStartupConnectorRole groupedStartupConnectorRole(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector) noexcept;
+        [[nodiscard]] std::vector<SDRMFormat>      groupedStartupRenderFormats(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector) noexcept;
+        [[nodiscard]] bool                        groupedStartupStateOnlyCurrent(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector,
+                                                                                const CSharedPointer<SOutputMode>& outputMode) noexcept;
+        [[nodiscard]] SGroupedStartupCommitResult  commitGroupedStartup(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector,
+                                                                        const CSharedPointer<SOutputMode>& outputMode, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                        const CSharedPointer<IBuffer>& buffer, bool onlyTest, uintptr_t transactionId, uint64_t deadlineNs,
+                                                                        const TGroupedTestKMSCaptureProvider& captureProvider) noexcept;
+        [[nodiscard]] bool                         groupedStartupActive(const CWeakPointer<CDRMBackend>& backend) noexcept;
         [[nodiscard]] SGroupedInitialFrameResult submitCurrentGroupedInitialFrame(const CWeakPointer<CDRMBackend>& backend, const POutputBridgeObservation& expected,
                                                                                   const NTiledAtomic::PResolvedTiledAtomicReplacement& replacement,
                                                                                   const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
@@ -293,6 +340,17 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
                                                                                      const NTiledAtomic::PResolvedTiledAtomicReplacement& replacement,
                                                                                      const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode) noexcept;
         [[nodiscard]] SGroupedTestProbeResult    probeCurrentGroupedTestModesetKey(const void* key, const TGroupedTestKMSCaptureProvider& captureProvider) noexcept;
+        [[nodiscard]] SGroupedStartupPrepareResult prepareGroupedStartupKey(const void* key, const CWeakPointer<CDRMBackend>& backend,
+                                                                            std::span<const CSharedPointer<SDRMConnector>> connectors,
+                                                                            const TGroupedTestKMSCaptureProvider&          captureProvider) noexcept;
+        [[nodiscard]] eGroupedStartupConnectorRole groupedStartupConnectorRoleKey(const void* key, const CSharedPointer<SDRMConnector>& connector) noexcept;
+        [[nodiscard]] std::vector<SDRMFormat>      groupedStartupRenderFormatsKey(const void* key, const CSharedPointer<SDRMConnector>& connector) noexcept;
+        [[nodiscard]] bool groupedStartupStateOnlyCurrentKey(const void* key, const CSharedPointer<SDRMConnector>& connector,
+                                                             const CSharedPointer<SOutputMode>& outputMode) noexcept;
+        [[nodiscard]] SGroupedStartupCommitResult commitGroupedStartupKey(const void* key, const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector,
+                                                                          const CSharedPointer<SOutputMode>& outputMode, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                          const CSharedPointer<IBuffer>& buffer, bool onlyTest, uintptr_t transactionId, uint64_t deadlineNs,
+                                                                          const TGroupedTestKMSCaptureProvider& captureProvider) noexcept;
         [[nodiscard]] SGroupedInitialFrameResult submitCurrentGroupedInitialFrameKey(const void* key, const POutputBridgeObservation& expected,
                                                                                      const NTiledAtomic::PResolvedTiledAtomicReplacement& replacement,
                                                                                      const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
@@ -351,6 +409,20 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
                                                                                          const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
     [[nodiscard]] AQ_TILED_DRM_PRIVATE SGroupedTestProbeResult   probeCurrentGroupedTestModeset(const CWeakPointer<CDRMBackend>&      backend,
                                                                                                 const TGroupedTestKMSCaptureProvider& captureProvider) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE SGroupedStartupPrepareResult prepareGroupedStartup(const CWeakPointer<CDRMBackend>&               backend,
+                                                                                          std::span<const CSharedPointer<SDRMConnector>> connectors,
+                                                                                          const TGroupedTestKMSCaptureProvider&          captureProvider) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE eGroupedStartupConnectorRole groupedStartupConnectorRole(const CWeakPointer<CDRMBackend>&     backend,
+                                                                                                const CSharedPointer<SDRMConnector>& connector) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE std::vector<SDRMFormat>     groupedStartupRenderFormats(const CWeakPointer<CDRMBackend>&     backend,
+                                                                                               const CSharedPointer<SDRMConnector>& connector) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE bool groupedStartupStateOnlyCurrent(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector,
+                                                                           const CSharedPointer<SOutputMode>& outputMode) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE SGroupedStartupCommitResult commitGroupedStartup(const CWeakPointer<CDRMBackend>& backend, const CSharedPointer<SDRMConnector>& connector,
+                                                                                        const CSharedPointer<SOutputMode>& outputMode, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                                        const CSharedPointer<IBuffer>& buffer, bool onlyTest, uintptr_t transactionId,
+                                                                                        uint64_t deadlineNs, const TGroupedTestKMSCaptureProvider& captureProvider) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE bool                        groupedStartupActive(const CWeakPointer<CDRMBackend>& backend) noexcept;
     [[nodiscard]] AQ_TILED_DRM_PRIVATE SOrdinaryKMSGateResult    gateOrdinaryKMS(const CWeakPointer<CDRMBackend>& backend, std::span<const SOrdinaryKMSCRTC> crtcs,
                                                                                  const std::function<bool()>& callback) noexcept;
     [[nodiscard]] AQ_TILED_DRM_PRIVATE SGroupedPageFlipResult    routeGroupedPageFlip(const CWeakPointer<CDRMBackend>& backend, uintptr_t transactionId, uint32_t crtcId,
diff --git a/src/backend/drm/TiledRuntimeAuthority.cpp b/src/backend/drm/TiledRuntimeAuthority.cpp
index bb1582066b20af22cf6a4fe2060947214aa7b80a..028c282b20c310ff6e18b52d31be1f7e47355fa4 100644
--- a/src/backend/drm/TiledRuntimeAuthority.cpp
+++ b/src/backend/drm/TiledRuntimeAuthority.cpp
@@ -225,6 +225,14 @@ SGroupedInitialFrameResult::operator bool() const noexcept {
     return status == eGroupedInitialFrameStatus::ACCEPTED;
 }
 
+SGroupedReplacementResult::operator bool() const noexcept {
+    return error == eTiledAtomicError::NONE && replacement;
+}
+
+SGroupedFrameResult::operator bool() const noexcept {
+    return status == eGroupedFrameStatus::ACCEPTED;
+}
+
 SOrdinaryKMSGateResult::operator bool() const noexcept {
     return status == eOrdinaryKMSGateStatus::EXECUTED;
 }
@@ -259,6 +267,33 @@ bool CGroupedRuntimeAuthority::exactCurrentRoute(const POutputBridgeObservation&
     return GROUP->modeSet()->physicalMappingFor(route->outputMode()) != nullptr;
 }
 
+bool CGroupedRuntimeAuthority::lockedFrameMatchesCurrent(const POutputBridgeObservation& current, const SRuntimeRecord& record, const PGroupedPublicationInstance& publication,
+                                                         const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer, uint64_t framebufferId,
+                                                         uint64_t bufferId) const noexcept {
+    if (!current || !record.identity || !record.activeRoute || !record.runtime || record.runtime->state() != eTiledRuntimeState::PUBLISHED_IDLE ||
+        record.runtime->preparedRoute() || record.runtime->preparedReservation() || record.completionDebt || !publication || !framebuffer || !buffer || framebufferId == 0 ||
+        bufferId == 0 || !sameOwner(record.activeRoute->generationOwner(), current) || !exactCurrentRoute(current, record.activeRoute) ||
+        !sameOwner(record.activeRoute->definitionIdentity(), record.identity) || !sameOwner(publication->definitionIdentity(), record.identity) ||
+        publication->m_transactionId != 0 || publication->m_accepted || publication->m_schedulerPending || publication->m_effectActive)
+        return false;
+
+    const auto& CURRENT_FRAMES = record.runtime->currentFrames();
+    if (CURRENT_FRAMES.size() != 1)
+        return false;
+    const auto& FRAME             = CURRENT_FRAMES.front();
+    const auto* FRAMEBUFFER_OWNER = FRAME.framebufferOwner.get();
+    const auto* BUFFER_OWNER      = FRAME.bufferOwner.get();
+    if (FRAME.framebufferId != framebufferId || FRAME.bufferId != bufferId || !FRAMEBUFFER_OWNER || !BUFFER_OWNER ||
+        FRAMEBUFFER_OWNER->role() != eGroupedFrameOwnerRole::FRAMEBUFFER || BUFFER_OWNER->role() != eGroupedFrameOwnerRole::BUFFER || !FRAMEBUFFER_OWNER->route() ||
+        !BUFFER_OWNER->route() || !sameOwner(FRAMEBUFFER_OWNER->route(), BUFFER_OWNER->route()) || !sameOwner(FRAMEBUFFER_OWNER->route()->definitionIdentity(), record.identity) ||
+        !sameOwner(BUFFER_OWNER->route()->definitionIdentity(), record.identity) || !sameOwner(FRAMEBUFFER_OWNER->publication(), publication) ||
+        !sameOwner(BUFFER_OWNER->publication(), publication) || !sameOwner(FRAMEBUFFER_OWNER->framebuffer(), framebuffer) || FRAMEBUFFER_OWNER->buffer() ||
+        BUFFER_OWNER->framebuffer() || !sameOwner(BUFFER_OWNER->buffer(), buffer))
+        return false;
+
+    return true;
+}
+
 CGroupedRuntimeAuthority::SRuntimeRecord* CGroupedRuntimeAuthority::recordFor(const POutputDefinitionIdentity& identity) noexcept {
     if (!identity)
         return nullptr;
@@ -425,23 +460,22 @@ SGroupedTestModesetResult CGroupedRuntimeAuthority::executeCurrentTestModesetUng
         if (COMMON_FORMATS.empty())
             return {.status = eGroupedTestModesetStatus::NO_COMMON_FORMAT};
 
-        const SPlaneFramebufferSize SIZE{.width = LOGICAL->width, .height = LOGICAL->height};
-        if (!validTestFramebuffer(m_testFramebuffer, SIZE, COMMON_FORMATS)) {
-            m_testFramebuffer.reset();
-            m_testFramebuffer = m_testFramebufferSource->acquire({
-                .device        = m_testDevice,
-                .backend       = m_testBackend,
-                .drmFD         = m_testDrmFD,
-                .size          = SIZE,
-                .commonFormats = COMMON_FORMATS,
-            });
-        }
-        if (!validTestFramebuffer(m_testFramebuffer, SIZE, COMMON_FORMATS)) {
-            m_testFramebuffer.reset();
-            return {.status = eGroupedTestModesetStatus::FRAMEBUFFER_UNAVAILABLE};
-        }
-
         if (!effectiveReplacement) {
+            const SPlaneFramebufferSize SIZE{.width = LOGICAL->width, .height = LOGICAL->height};
+            if (!validTestFramebuffer(m_testFramebuffer, SIZE, COMMON_FORMATS)) {
+                m_testFramebuffer.reset();
+                m_testFramebuffer = m_testFramebufferSource->acquire({
+                    .device        = m_testDevice,
+                    .backend       = m_testBackend,
+                    .drmFD         = m_testDrmFD,
+                    .size          = SIZE,
+                    .commonFormats = COMMON_FORMATS,
+                });
+            }
+            if (!validTestFramebuffer(m_testFramebuffer, SIZE, COMMON_FORMATS)) {
+                m_testFramebuffer.reset();
+                return {.status = eGroupedTestModesetStatus::FRAMEBUFFER_UNAVAILABLE};
+            }
             auto capture = (*captureProvider)();
             if (!capture)
                 return {.status = eGroupedTestModesetStatus::ROUTE_INVALID, .routeError = eTiledAtomicError::INCOMPLETE_REPLACEMENT};
@@ -503,11 +537,18 @@ SGroupedTestModesetResult CGroupedRuntimeAuthority::executeCurrentTestModesetUng
         const auto& FRAMEBUFFER_OWNER = effectiveReplacement->targetFramebufferOwner();
         const auto  LIFETIME          = SNAPSHOT->device()->backend().lock();
         if (!FRAMEBUFFER_OWNER || !LIFETIME || FRAMEBUFFER_OWNER->dead() || !sameOwner(FRAMEBUFFER_OWNER->generationOwner(), current) ||
-            !sameOwner(FRAMEBUFFER_OWNER->backend(), LIFETIME) || FRAMEBUFFER_OWNER->framebuffer() != ROUTE->framebuffer() || ROUTE->framebuffer() != m_testFramebuffer->atomic)
-            return {.status = eGroupedTestModesetStatus::ROUTE_INVALID, .routeError = eTiledAtomicError::FRAMEBUFFER_MISMATCH};
-        if (LIFETIME->binding() == eBackendBinding::PRODUCTION_BACKEND &&
-            (!sameOwner(FRAMEBUFFER_OWNER->drmFramebuffer(), m_testFramebuffer->framebuffer) || !sameOwner(FRAMEBUFFER_OWNER->buffer(), m_testFramebuffer->buffer)))
+            !sameOwner(FRAMEBUFFER_OWNER->backend(), LIFETIME) || FRAMEBUFFER_OWNER->framebuffer() != ROUTE->framebuffer())
             return {.status = eGroupedTestModesetStatus::ROUTE_INVALID, .routeError = eTiledAtomicError::FRAMEBUFFER_MISMATCH};
+        if (LIFETIME->binding() == eBackendBinding::PRODUCTION_BACKEND) {
+            const auto DRM_FRAMEBUFFER = FRAMEBUFFER_OWNER->drmFramebuffer();
+            const auto BUFFER          = FRAMEBUFFER_OWNER->buffer();
+            const auto ATTRS           = BUFFER ? BUFFER->dmabuf() : SDMABUFAttrs{};
+            if (!DRM_FRAMEBUFFER || !BUFFER || DRM_FRAMEBUFFER->id != ROUTE->framebuffer().id || DRM_FRAMEBUFFER->dead || !sameOwner(DRM_FRAMEBUFFER->buffer.lock(), BUFFER) ||
+                !ATTRS.success || ATTRS.size.x != static_cast<double>(ROUTE->framebuffer().size.width) || ATTRS.size.y != static_cast<double>(ROUTE->framebuffer().size.height) ||
+                ATTRS.format != ROUTE->framebuffer().format || ATTRS.modifier != ROUTE->framebuffer().modifier ||
+                !supportsExactFormat(COMMON_FORMATS, ATTRS.format, ATTRS.modifier))
+                return {.status = eGroupedTestModesetStatus::ROUTE_INVALID, .routeError = eTiledAtomicError::FRAMEBUFFER_MISMATCH};
+        }
 
         SGroupedTestModesetResult result;
         result.cleanup = m_testCleanupRegistry->retryPending();
@@ -534,6 +575,115 @@ SGroupedTestModesetResult CGroupedRuntimeAuthority::executeCurrentTestModesetUng
     } catch (...) { return {.status = eGroupedTestModesetStatus::ALLOCATION_FAILED}; }
 }
 
+SGroupedReplacementResult CGroupedRuntimeAuthority::resolveCurrentReplacement(const POutputBridgeObservation& current, const PScanGroupDefinition& group,
+                                                                              const CSharedPointer<SOutputMode>& outputMode, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                              const CSharedPointer<IBuffer>&        buffer,
+                                                                              const TGroupedTestKMSCaptureProvider& captureProvider) noexcept {
+    if (!onEventThread() || m_mutationActive || m_terminal || !m_testDevice || m_testDrmFD < 0 || !current || !group || !outputMode || !framebuffer || !buffer || !captureProvider)
+        return {.error = eTiledAtomicError::INVALID_INPUT};
+
+    m_mutationActive = true;
+    Hyprutils::Utils::CScopeGuard mutationGuard([&] { m_mutationActive = false; });
+    try {
+        const auto& SNAPSHOT = current->capturedSnapshot();
+        const auto* GROUP    = current->findGroup(group);
+        const auto  LIFETIME = m_testDevice->backend().lock();
+        const auto  BACKEND  = m_testBackend.lock();
+        if (!SNAPSHOT || !sameOwner(SNAPSHOT->device(), m_testDevice) || !GROUP || !sameOwner(GROUP->scanDefinition(), group) ||
+            GROUP->projection() != eGroupProjection::MULTI_STREAM_ALLOCATED || !GROUP->definitionIdentity() || !LIFETIME ||
+            LIFETIME->binding() != eBackendBinding::PRODUCTION_BACKEND || !BACKEND || BACKEND->drmFD() != m_testDrmFD || LIFETIME->drmBackend().impl_ != m_testBackend.impl_)
+            return {.error = eTiledAtomicError::INVALID_GENERATION};
+
+        const auto& MODE_SET  = GROUP->modeSet();
+        const auto  ALLOCATED = GROUP->allocation();
+        const auto* LOGICAL   = MODE_SET ? MODE_SET->logicalModeFor(outputMode) : nullptr;
+        const auto* MAPPING   = MODE_SET ? MODE_SET->physicalMappingFor(outputMode) : nullptr;
+        if (!MODE_SET || !ALLOCATED || ALLOCATED->get().status() != eGroupStatus::ALLOCATED || !LOGICAL || !MAPPING || outputMode->modeInfo.has_value() ||
+            outputMode->pixelSize.x != static_cast<double>(LOGICAL->width) || outputMode->pixelSize.y != static_cast<double>(LOGICAL->height) ||
+            outputMode->refreshRate != LOGICAL->refreshRate || outputMode->preferred != LOGICAL->preferred)
+            return {.error = eTiledAtomicError::MODE_MAPPING_MISMATCH};
+
+        std::vector<SPlaneFormatSet> planeFormats;
+        planeFormats.reserve(group->group().members.size());
+        size_t primaryMember = group->group().members.size();
+        for (size_t index = 0; index < group->group().members.size(); ++index) {
+            const auto& MEMBER = group->group().members.at(index);
+            const auto  BINDING =
+                std::ranges::find(ALLOCATED->get().bindings(), MEMBER.connectorId, [](const auto& candidate) { return candidate.connector() ? candidate.connector()->id : 0; });
+            if (BINDING == ALLOCATED->get().bindings().end() || !BINDING->tiled() || !BINDING->primaryPlane() || !sameOwner(BINDING->definition(), GROUP->allocationDefinition()))
+                return {.error = eTiledAtomicError::ALLOCATION_MISMATCH};
+            planeFormats.push_back({.formats = BINDING->primaryPlane()->formats});
+            if (MEMBER.connectorId == group->group().primaryConnector)
+                primaryMember = index;
+        }
+        const auto COMMON_FORMATS = intersectPlaneFormats(planeFormats, primaryMember);
+        if (COMMON_FORMATS.empty())
+            return {.error = eTiledAtomicError::FRAMEBUFFER_MISMATCH};
+
+        const auto FRAMEBUFFER_BUFFER = framebuffer->buffer.lock();
+        const auto ATTRS              = buffer->dmabuf();
+        if (framebuffer->id == 0 || framebuffer->dead || framebuffer->backend.impl_ != m_testBackend.impl_ || !sameOwner(FRAMEBUFFER_BUFFER, buffer) || !ATTRS.success ||
+            ATTRS.format == DRM_FORMAT_INVALID || ATTRS.size.x != outputMode->pixelSize.x || ATTRS.size.y != outputMode->pixelSize.y || ATTRS.size.x <= 0 || ATTRS.size.y <= 0 ||
+            ATTRS.size.x > static_cast<double>(std::numeric_limits<uint32_t>::max()) || ATTRS.size.y > static_cast<double>(std::numeric_limits<uint32_t>::max()) ||
+            std::trunc(ATTRS.size.x) != ATTRS.size.x || std::trunc(ATTRS.size.y) != ATTRS.size.y || !supportsExactFormat(COMMON_FORMATS, ATTRS.format, ATTRS.modifier))
+            return {.error = eTiledAtomicError::FRAMEBUFFER_MISMATCH};
+
+        const STiledAtomicFramebuffer ATOMIC_FRAMEBUFFER{
+            .id       = framebuffer->id,
+            .size     = {.width = static_cast<uint32_t>(ATTRS.size.x), .height = static_cast<uint32_t>(ATTRS.size.y)},
+            .format   = ATTRS.format,
+            .modifier = ATTRS.modifier,
+        };
+        const auto RESOLVED_ROUTE = resolveCapturedTiledAtomic({
+            .generationOwner    = current,
+            .groupDefinition    = group,
+            .definitionIdentity = GROUP->definitionIdentity(),
+            .outputMode         = outputMode,
+            .framebuffer        = ATOMIC_FRAMEBUFFER,
+        });
+        if (!RESOLVED_ROUTE)
+            return {.error = RESOLVED_ROUTE.error};
+
+        auto capture = captureProvider();
+        if (!capture)
+            return {.error = eTiledAtomicError::INCOMPLETE_REPLACEMENT};
+        const auto TARGET_FRAMEBUFFER = CTiledAtomicFramebufferOwner::createCurrent(current, framebuffer);
+        if (!TARGET_FRAMEBUFFER)
+            return {.error = eTiledAtomicError::FRAMEBUFFER_MISMATCH};
+
+        std::vector<STiledPlaneInventoryResource> planeResources;
+        std::vector<STiledPlaneInventoryState>    planeStates;
+        planeResources.reserve(capture->planes.size());
+        planeStates.reserve(capture->planes.size());
+        for (auto& plane : capture->planes) {
+            PAtomicFramebufferOwner liveFramebuffer;
+            if (plane.framebuffer)
+                liveFramebuffer = CTiledAtomicFramebufferOwner::createCurrent(current, plane.framebuffer);
+            if ((plane.framebufferId != 0 || plane.crtcId != 0) && !liveFramebuffer)
+                return {.error = eTiledAtomicError::FRAMEBUFFER_MISMATCH};
+            planeResources.push_back({.id = plane.id, .owner = plane.owner, .role = plane.role});
+            planeStates.push_back({
+                .id               = plane.id,
+                .owner            = plane.owner,
+                .crtcId           = plane.crtcId,
+                .framebufferId    = plane.framebufferId,
+                .framebufferOwner = std::move(liveFramebuffer),
+            });
+        }
+        const auto INVENTORY = CTiledAtomicPlaneInventory::create(current, std::move(planeResources), std::move(planeStates));
+        if (!INVENTORY)
+            return {.error = eTiledAtomicError::INCOMPLETE_REPLACEMENT};
+        const auto RESOLVED_REPLACEMENT = resolveTiledAtomicReplacement({
+            .targetRoute            = RESOLVED_ROUTE.route,
+            .targetFramebufferOwner = TARGET_FRAMEBUFFER,
+            .planeInventory         = INVENTORY,
+            .connectors             = std::move(capture->connectors),
+            .crtcs                  = std::move(capture->crtcs),
+        });
+        return {.replacement = RESOLVED_REPLACEMENT.replacement, .error = RESOLVED_REPLACEMENT.error};
+    } catch (...) { return {.error = eTiledAtomicError::ALLOCATION_FAILED}; }
+}
+
 SGroupedInitialFrameResult CGroupedRuntimeAuthority::submitInitialCurrent(const POutputBridgeObservation& current, const PResolvedTiledAtomicReplacement& replacement,
                                                                           const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
                                                                           const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer,
@@ -714,6 +864,163 @@ SGroupedInitialFrameResult CGroupedRuntimeAuthority::submitInitialCurrent(const
     } catch (...) { return {.status = preacceptInvariantFailure ? eGroupedInitialFrameStatus::PREACCEPT_INVARIANT_FAILURE : eGroupedInitialFrameStatus::ALLOCATION_FAILED}; }
 }
 
+SGroupedFrameResult CGroupedRuntimeAuthority::submitFrameCurrent(const POutputBridgeObservation& current, const PScanGroupDefinition& group,
+                                                                 const CSharedPointer<SOutputMode>& outputMode, const PGroupedPublicationInstance& publication,
+                                                                 const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId,
+                                                                 uint64_t deadlineNs) noexcept {
+    if (!onEventThread())
+        return {.status = eGroupedFrameStatus::WRONG_THREAD, .failureReason = eGroupedFrameFailureReason::NONE};
+    if (m_mutationActive)
+        return {.status = eGroupedFrameStatus::BUSY, .failureReason = eGroupedFrameFailureReason::NONE};
+    if (m_terminal)
+        return {.status = eGroupedFrameStatus::TERMINAL, .failureReason = eGroupedFrameFailureReason::NONE};
+    if (!m_testDevice || m_testDrmFD < 0 || !m_testOperations)
+        return {.status = eGroupedFrameStatus::NOT_CONFIGURED, .failureReason = eGroupedFrameFailureReason::NONE};
+    if (!current || !group || !outputMode || transactionId == 0 || deadlineNs == 0)
+        return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::INPUT_CURRENT};
+    if (!publication)
+        return {.status = eGroupedFrameStatus::INVALID_PUBLICATION, .failureReason = eGroupedFrameFailureReason::NONE};
+    if (!framebuffer || !buffer)
+        return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::INPUT_FRAMEBUFFER};
+
+    m_mutationActive = true;
+    Hyprutils::Utils::CScopeGuard mutationGuard([&] { m_mutationActive = false; });
+    try {
+        const auto& SNAPSHOT = current->capturedSnapshot();
+        const auto* GROUP    = current->findGroup(group);
+        const auto  LIFETIME = m_testDevice->backend().lock();
+        const auto  BACKEND  = m_testBackend.lock();
+        if (!SNAPSHOT)
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::SNAPSHOT};
+        if (!sameOwner(SNAPSHOT->device(), m_testDevice))
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::DEVICE};
+        if (!GROUP)
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::GROUP};
+        if (!sameOwner(GROUP->scanDefinition(), group))
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::GROUP_OWNER};
+        if (GROUP->projection() != eGroupProjection::MULTI_STREAM_ALLOCATED)
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::GROUP_PROJECTION};
+        if (!GROUP->definitionIdentity())
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::GROUP_IDENTITY};
+        if (!sameOwner(publication->definitionIdentity(), GROUP->definitionIdentity()))
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::PUBLICATION_IDENTITY};
+        if (!LIFETIME)
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::LIFETIME};
+        if (LIFETIME->binding() != eBackendBinding::PRODUCTION_BACKEND)
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::LIFETIME_BINDING};
+        if (!BACKEND)
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::BACKEND};
+        if (BACKEND->drmFD() != m_testDrmFD)
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::DRM_FD};
+        if (LIFETIME->drmBackend().impl_ != m_testBackend.impl_)
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::DRM_BACKEND};
+
+        const auto FRAMEBUFFER_BUFFER = framebuffer->buffer.lock();
+        const auto ATTRS              = buffer->dmabuf();
+        if (framebuffer->id == 0)
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::FRAMEBUFFER_ID};
+        if (framebuffer->dead)
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::FRAMEBUFFER_DEAD};
+        if (framebuffer->backend.impl_ != m_testBackend.impl_)
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::FRAMEBUFFER_BACKEND};
+        if (!sameOwner(FRAMEBUFFER_BUFFER, buffer))
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::FRAMEBUFFER_BUFFER_OWNER};
+        if (!ATTRS.success)
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::DMABUF_INVALID};
+        if (ATTRS.format == DRM_FORMAT_INVALID)
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::DMABUF_FORMAT};
+        if (ATTRS.size.x <= 0 || ATTRS.size.y <= 0 || ATTRS.size.x > static_cast<double>(std::numeric_limits<uint32_t>::max()) ||
+            ATTRS.size.y > static_cast<double>(std::numeric_limits<uint32_t>::max()))
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::DMABUF_SIZE};
+        if (std::trunc(ATTRS.size.x) != ATTRS.size.x || std::trunc(ATTRS.size.y) != ATTRS.size.y)
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::DMABUF_SIZE_INTEGRAL};
+        const STiledAtomicFramebuffer ATOMIC_FRAMEBUFFER{
+            .id       = framebuffer->id,
+            .size     = {.width = static_cast<uint32_t>(ATTRS.size.x), .height = static_cast<uint32_t>(ATTRS.size.y)},
+            .format   = ATTRS.format,
+            .modifier = ATTRS.modifier,
+        };
+        const auto RESOLVED = resolveCapturedTiledAtomic({
+            .generationOwner    = current,
+            .groupDefinition    = group,
+            .definitionIdentity = GROUP->definitionIdentity(),
+            .outputMode         = outputMode,
+            .framebuffer        = ATOMIC_FRAMEBUFFER,
+        });
+        if (!RESOLVED)
+            return {.status = eGroupedFrameStatus::ROUTE_INVALID, .failureReason = eGroupedFrameFailureReason::NONE, .routeError = RESOLVED.error};
+        auto* const RECORD = recordFor(GROUP->definitionIdentity());
+        if (!RECORD || !RECORD->runtime || RECORD->runtime->state() != eTiledRuntimeState::PUBLISHED_IDLE || !RECORD->activeRoute || !synchronizeRoute(*RECORD))
+            return {.status = eGroupedFrameStatus::RUNTIME_NOT_STARTED, .failureReason = eGroupedFrameFailureReason::NONE, .routeError = eTiledAtomicError::NONE};
+        if (!exactCurrentRoute(current, RESOLVED.route))
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::RESOLVED_ROUTE_CURRENT};
+        if (!RESOLVED.route->matchesRuntimePlan(RECORD->runtime->activePlan()))
+            return {.status = eGroupedFrameStatus::INVALID_CURRENT, .failureReason = eGroupedFrameFailureReason::RUNTIME_PLAN};
+
+        const auto BUFFER_ID = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(buffer.impl_));
+        if (buffer->lockedByBackend && !lockedFrameMatchesCurrent(current, *RECORD, publication, framebuffer, buffer, framebuffer->id, BUFFER_ID))
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::BUFFER_LOCKED};
+
+        const auto MAKE_OWNER = [&](eGroupedFrameOwnerRole role, const CSharedPointer<CDRMFB>& retainedFramebuffer,
+                                    const CSharedPointer<IBuffer>& retainedBuffer) -> PGroupedFrameOwner {
+            CSharedPointer<CGroupedFrameOwner>       mutableOwner{new CGroupedFrameOwner{role, RESOLVED.route, publication, retainedFramebuffer, retainedBuffer}};
+            CSharedPointer<const CGroupedFrameOwner> retained = mutableOwner;
+            return PGroupedFrameOwner{std::move(retained)};
+        };
+        const auto FRAMEBUFFER_OWNER = MAKE_OWNER(eGroupedFrameOwnerRole::FRAMEBUFFER, framebuffer, {});
+        const auto BUFFER_OWNER      = MAKE_OWNER(eGroupedFrameOwnerRole::BUFFER, {}, buffer);
+        if (!FRAMEBUFFER_OWNER || !BUFFER_OWNER || BUFFER_ID == 0)
+            return {.status = eGroupedFrameStatus::INVALID_FRAMEBUFFER, .failureReason = eGroupedFrameFailureReason::OWNER_ALLOCATION};
+        if (!publication->arm(transactionId))
+            return {.status = eGroupedFrameStatus::INVALID_PUBLICATION, .failureReason = eGroupedFrameFailureReason::NONE};
+        bool                          kmsAccepted      = false;
+        bool                          publicationArmed = true;
+        Hyprutils::Utils::CScopeGuard publicationGuard([&] {
+            if (publicationArmed && !kmsAccepted && !publication->rollback(transactionId))
+                std::terminate();
+        });
+
+        auto                          transaction = submitTiledFrameTransaction(RESOLVED.route, *RECORD->runtime, m_reservations,
+                                                                                {
+                                                                                    .framebufferId    = framebuffer->id,
+                                                                                    .bufferId         = BUFFER_ID,
+                                                                                    .framebufferOwner = FRAMEBUFFER_OWNER,
+                                                                                    .bufferOwner      = BUFFER_OWNER,
+                                                                                },
+                                                                                transactionId, deadlineNs, m_testDrmFD, m_testOperations);
+        kmsAccepted                               = transaction.effects.kmsAccepted;
+        if (!kmsAccepted) {
+            const bool ROLLED_BACK = publication->rollback(transactionId);
+            publicationArmed       = false;
+            return {
+                .status        = ROLLED_BACK ? eGroupedFrameStatus::TRANSACTION_FAILED : eGroupedFrameStatus::ACCEPTED_INVARIANT_FAILURE,
+                .failureReason = eGroupedFrameFailureReason::NONE,
+                .routeError    = eTiledAtomicError::NONE,
+                .route         = RESOLVED.route,
+                .transaction   = transaction,
+            };
+        }
+
+        buffer->lockedByBackend         = true;
+        const bool PUBLICATION_ACCEPTED = publication->accept(transactionId, transaction.effects.runtimeAccept.schedulerSubmit);
+        if (!PUBLICATION_ACCEPTED) {
+            const auto EFFECTS = RECORD->runtime->quiesce(eTiledQuiesceReason::EVENT_INVARIANT);
+            static_cast<void>(applyReservationEffects(EFFECTS));
+        }
+        RECORD->activeRoute = RESOLVED.route;
+        return {
+            .status                = PUBLICATION_ACCEPTED && transaction.status == eTiledFrameTransactionStatus::ACCEPTED ? eGroupedFrameStatus::ACCEPTED :
+                                                                                                                            eGroupedFrameStatus::ACCEPTED_INVARIANT_FAILURE,
+            .failureReason         = eGroupedFrameFailureReason::NONE,
+            .routeError            = eTiledAtomicError::NONE,
+            .route                 = RESOLVED.route,
+            .transaction           = transaction,
+            .bufferLocked          = true,
+            .submitEffectDelivered = PUBLICATION_ACCEPTED && transaction.effects.runtimeAccept.schedulerSubmit,
+        };
+    } catch (...) { return {.status = eGroupedFrameStatus::ALLOCATION_FAILED, .failureReason = eGroupedFrameFailureReason::NONE}; }
+}
+
 bool CGroupedRuntimeAuthority::prepareTestModesetDetach() noexcept {
     if (!onEventThread() || m_mutationActive)
         return false;
diff --git a/src/backend/drm/TiledRuntimeAuthority.hpp b/src/backend/drm/TiledRuntimeAuthority.hpp
index 2b7a3d3134c0b87d755f1eec65c9cecb7ecdf61d..455c72fe2eccfe433ac43cc0382b707c328d9014 100644
--- a/src/backend/drm/TiledRuntimeAuthority.hpp
+++ b/src/backend/drm/TiledRuntimeAuthority.hpp
@@ -274,6 +274,74 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
         explicit                                   operator bool() const noexcept;
     };
 
+    struct AQ_TILED_RUNTIME_AUTHORITY_PRIVATE SGroupedReplacementResult {
+        NTiledAtomic::PResolvedTiledAtomicReplacement replacement;
+        NTiledAtomic::eTiledAtomicError               error = NTiledAtomic::eTiledAtomicError::INVALID_INPUT;
+
+        explicit                                      operator bool() const noexcept;
+    };
+
+    enum class eGroupedFrameStatus : uint8_t {
+        ACCEPTED = 0,
+        ACCEPTED_INVARIANT_FAILURE,
+        WRONG_THREAD,
+        BUSY,
+        TERMINAL,
+        NOT_CONFIGURED,
+        INVALID_CURRENT,
+        INVALID_PUBLICATION,
+        INVALID_FRAMEBUFFER,
+        ROUTE_INVALID,
+        RUNTIME_NOT_STARTED,
+        TRANSACTION_FAILED,
+        ALLOCATION_FAILED,
+    };
+
+    // Source-private diagnostic for the exact fail-closed condition selected
+    // before a normal grouped transaction can be built.
+    enum class eGroupedFrameFailureReason : uint8_t {
+        NONE = 0,
+        NOT_INVOKED,
+        INPUT_CURRENT,
+        INPUT_FRAMEBUFFER,
+        SNAPSHOT,
+        DEVICE,
+        GROUP,
+        GROUP_OWNER,
+        GROUP_PROJECTION,
+        GROUP_IDENTITY,
+        PUBLICATION_IDENTITY,
+        LIFETIME,
+        LIFETIME_BINDING,
+        BACKEND,
+        DRM_FD,
+        DRM_BACKEND,
+        FRAMEBUFFER_ID,
+        FRAMEBUFFER_DEAD,
+        FRAMEBUFFER_BACKEND,
+        FRAMEBUFFER_BUFFER_OWNER,
+        BUFFER_LOCKED,
+        DMABUF_INVALID,
+        DMABUF_FORMAT,
+        DMABUF_SIZE,
+        DMABUF_SIZE_INTEGRAL,
+        RESOLVED_ROUTE_CURRENT,
+        RUNTIME_PLAN,
+        OWNER_ALLOCATION,
+    };
+
+    struct AQ_TILED_RUNTIME_AUTHORITY_PRIVATE SGroupedFrameResult {
+        eGroupedFrameStatus                        status        = eGroupedFrameStatus::INVALID_CURRENT;
+        eGroupedFrameFailureReason                 failureReason = eGroupedFrameFailureReason::NOT_INVOKED;
+        NTiledAtomic::eTiledAtomicError            routeError    = NTiledAtomic::eTiledAtomicError::INVALID_INPUT;
+        NTiledAtomic::PResolvedTiledAtomicRoute    route;
+        NTiledAtomic::STiledFrameTransactionResult transaction;
+        bool                                       bufferLocked          = false;
+        bool                                       submitEffectDelivered = false;
+
+        explicit                                   operator bool() const noexcept;
+    };
+
     struct AQ_TILED_RUNTIME_AUTHORITY_PRIVATE SOrdinaryKMSCRTC {
         CSharedPointer<SDRMCRTC> owner;
         uint32_t                 id = 0;
@@ -398,6 +466,13 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
                                                                       const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
                                                                       const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer,
                                                                       const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId, uint64_t deadlineNs) noexcept;
+        [[nodiscard]] SGroupedReplacementResult  resolveCurrentReplacement(const POutputBridgeObservation& current, const PScanGroupDefinition& group,
+                                                                           const CSharedPointer<SOutputMode>& outputMode, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                           const CSharedPointer<IBuffer>& buffer, const TGroupedTestKMSCaptureProvider& captureProvider) noexcept;
+        [[nodiscard]] SGroupedFrameResult        submitFrameCurrent(const POutputBridgeObservation& current, const PScanGroupDefinition& group,
+                                                                    const CSharedPointer<SOutputMode>& outputMode, const PGroupedPublicationInstance& publication,
+                                                                    const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId,
+                                                                    uint64_t deadlineNs) noexcept;
         [[nodiscard]] SOrdinaryKMSGateResult     gateOrdinaryKMS(std::span<const SOrdinaryKMSCRTC> crtcs, const std::function<bool()>& callback) noexcept;
         [[nodiscard]] SGroupedPageFlipResult     routePageFlip(uintptr_t transactionId, uint32_t crtcId, uint32_t sequence, uint64_t timestampNs) noexcept;
         [[nodiscard]] SGroupedQuiesceResult      quiesceAll(eTiledQuiesceReason reason) noexcept;
@@ -430,8 +505,11 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
 
         using TRuntimeMap = std::map<const void*, SRuntimeRecord>;
 
-        [[nodiscard]] bool                            onEventThread() const noexcept;
-        [[nodiscard]] bool                            exactCurrentRoute(const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route) const noexcept;
+        [[nodiscard]] bool onEventThread() const noexcept;
+        [[nodiscard]] bool exactCurrentRoute(const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route) const noexcept;
+        [[nodiscard]] bool lockedFrameMatchesCurrent(const POutputBridgeObservation& current, const SRuntimeRecord& record, const PGroupedPublicationInstance& publication,
+                                                     const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer, uint64_t framebufferId,
+                                                     uint64_t bufferId) const noexcept;
         [[nodiscard]] eGroupedStageResult             stageRecord(const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route);
         [[nodiscard]] bool                            applyReservationEffects(const CGroupedRuntime::SEffects& effects) noexcept;
         [[nodiscard]] bool                            synchronizeRoute(SRuntimeRecord& record) noexcept;
diff --git a/tests/TiledAtomic.cpp b/tests/TiledAtomic.cpp
index 1b92d627a9ebc1b5507e85ff320b599d9f964287..40b5dc4e2eb5443f01e1fb7c898329e4a1d70669 100644
--- a/tests/TiledAtomic.cpp
+++ b/tests/TiledAtomic.cpp
@@ -106,6 +106,23 @@ using Hyprutils::Memory::CWeakPointer;
 using Hyprutils::Memory::makeShared;
 
 namespace Aquamarine::NDRM::NTiledRuntimeAuthorityTest {
+    class CTestBuffer final : public IBuffer {
+      public:
+        eBufferCapability caps() override {
+            return BUFFER_CAPABILITY_NONE;
+        }
+        eBufferType type() override {
+            return BUFFER_TYPE_DMABUF;
+        }
+        void update(const Hyprutils::Math::CRegion&) override {}
+        bool isSynchronous() override {
+            return false;
+        }
+        bool good() override {
+            return true;
+        }
+    };
+
     class __attribute__((visibility("hidden"))) CRecordingPublicationSink final : public IGroupedPublicationEffectSink { // NOLINT(misc-use-internal-linkage)
       public:
         void frameSubmitted(uintptr_t transactionId) noexcept override {
@@ -125,6 +142,13 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthorityTest {
                 const auto* OWNER = release.owner.get();
                 return release.bufferId != 0 && OWNER && OWNER->role() == eGroupedFrameOwnerRole::BUFFER && OWNER->buffer() && OWNER->publication();
             });
+            if (unlockReleases) {
+                for (const auto& RELEASE : releases) {
+                    const auto* OWNER = RELEASE.owner.get();
+                    if (OWNER && OWNER->role() == eGroupedFrameOwnerRole::BUFFER && OWNER->buffer())
+                        OWNER->buffer()->lockedByBackend = false;
+                }
+            }
             if (onCompleted)
                 onCompleted();
         }
@@ -135,6 +159,7 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthorityTest {
         uintptr_t                 submittedToken  = 0;
         uintptr_t                 completionToken = 0;
         bool                      releasesValid   = false;
+        bool                      unlockReleases  = false;
         PResolvedTiledAtomicRoute completionRoute;
         std::function<void()>     onSubmitted;
         std::function<void()>     onCompleted;
@@ -199,6 +224,13 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthorityTest {
             return RECORD && RECORD->completionDebt && RECORD->completionDebt->transactionId == transactionId;
         }
 
+        static bool lockedFrameMatchesCurrent(CGroupedRuntimeAuthority& authority, const POutputBridgeObservation& current, const POutputDefinitionIdentity& identity,
+                                              const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer,
+                                              uint64_t framebufferId, uint64_t bufferId) {
+            const auto* RECORD = authority.recordFor(identity);
+            return RECORD && authority.lockedFrameMatchesCurrent(current, *RECORD, publication, framebuffer, buffer, framebufferId, bufferId);
+        }
+
         static bool publishIdle(CGroupedRuntimeAuthority& authority, const POutputDefinitionIdentity& identity, const PGroupedPublicationInstance& publication,
                                 const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer, uint64_t firstFramebufferId, uint64_t bufferId) {
             auto* const RECORD = authority.recordFor(identity);
@@ -337,6 +369,7 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthorityTest {
 
 using Aquamarine::NDRM::NTiledRuntimeAuthorityTest::CFixtureAuthority;
 using Aquamarine::NDRM::NTiledRuntimeAuthorityTest::CRecordingPublicationSink;
+using Aquamarine::NDRM::NTiledRuntimeAuthorityTest::CTestBuffer;
 
 namespace {
     int  FAILURES = 0;
@@ -1853,11 +1886,12 @@ int main() {
         bool completionReentry       = true;
         publicationSink->onSubmitted = [&] { submitReentry = CFixtureAuthority::arm(publication, 5'006); };
         publicationSink->onCompleted = [&] { completionReentry = CFixtureAuthority::arm(publication, 5'007); };
-        CWeakPointer<CDRMFB>  newFramebufferWeak;
-        CWeakPointer<IBuffer> newBufferWeak;
-        auto                  newFramebuffer = CFixtureAuthority::opaqueResource<CDRMFB>(&newFramebufferWeak);
-        auto                  newBuffer      = CFixtureAuthority::opaqueResource<IBuffer>(&newBufferWeak);
+        CWeakPointer<CDRMFB>    newFramebufferWeak;
+        auto                    newFramebuffer = CFixtureAuthority::opaqueResource<CDRMFB>(&newFramebufferWeak);
+        CSharedPointer<IBuffer> newBuffer      = makeShared<CTestBuffer>();
+        CWeakPointer<IBuffer>   newBufferWeak  = newBuffer;
         CHECK(CFixtureAuthority::accept(authority, GROUP.definitionIdentity(), publication, newFramebuffer, newBuffer, 5'005, 1'101, 90'000));
+        newBuffer->lockedByBackend = true;
         newFramebuffer.reset();
         newBuffer.reset();
         CHECK(!submitReentry);
@@ -1944,10 +1978,53 @@ int main() {
         CHECK(CFixtureAuthority::rollback(publication, 5'008));
         CHECK(CFixtureAuthority::activeGeneration(authority, GROUP.definitionIdentity()) == successorResolved.route->generation());
 
-        const auto stale = authority.routePageFlip(5'005, resolved.route->crtcIds().back(), 42, 222);
+        auto currentFramebuffer = newFramebufferWeak.lock();
+        auto currentBuffer      = newBufferWeak.lock();
+        CHECK(!!currentFramebuffer);
+        CHECK(!!currentBuffer);
+        CHECK(currentBuffer->lockedByBackend);
+        CHECK(CFixtureAuthority::lockedFrameMatchesCurrent(authority, successorInstalled, GROUP.definitionIdentity(), publication, currentFramebuffer, currentBuffer,
+                                                           successorResolved.route->framebuffer().id, 1'101));
+
+        auto                    foreignFramebuffer = CFixtureAuthority::opaqueResource<CDRMFB>();
+        CSharedPointer<IBuffer> foreignBuffer      = makeShared<CTestBuffer>();
+        foreignBuffer->lockedByBackend             = true;
+        CHECK(!CFixtureAuthority::lockedFrameMatchesCurrent(authority, successorInstalled, GROUP.definitionIdentity(), publication, foreignFramebuffer, currentBuffer,
+                                                            successorResolved.route->framebuffer().id, 1'101));
+        CHECK(!CFixtureAuthority::lockedFrameMatchesCurrent(authority, successorInstalled, GROUP.definitionIdentity(), publication, currentFramebuffer, foreignBuffer,
+                                                            successorResolved.route->framebuffer().id, 1'102));
+
+        CHECK(CFixtureAuthority::accept(authority, GROUP.definitionIdentity(), publication, currentFramebuffer, currentBuffer, 5'009, 1'101, 91'000));
+        const auto SAME_FIRST = authority.routePageFlip(5'009, successorResolved.route->crtcIds().front(), 43, 230);
+        CHECK(SAME_FIRST.disposition == eGroupedPageFlipDisposition::RECORDED);
+        const auto SAME_COMPLETION = authority.routePageFlip(5'009, successorResolved.route->crtcIds().back(), 44, 240);
+        CHECK(SAME_COMPLETION.disposition == eGroupedPageFlipDisposition::COMPLETED);
+        CHECK(SAME_COMPLETION.completionDelivered);
+        CHECK(SAME_COMPLETION.releasesDelivered == 0);
+        CHECK(publicationSink->releaseCount == 0);
+        CHECK(currentBuffer->lockedByBackend);
+
+        auto                    differentFramebuffer = CFixtureAuthority::opaqueResource<CDRMFB>();
+        CSharedPointer<IBuffer> differentBuffer      = makeShared<CTestBuffer>();
+        differentBuffer->lockedByBackend             = true;
+        publicationSink->unlockReleases              = true;
+        CHECK(CFixtureAuthority::accept(authority, GROUP.definitionIdentity(), publication, differentFramebuffer, differentBuffer, 5'010, 1'102, 92'000));
+        const auto DIFFERENT_FIRST = authority.routePageFlip(5'010, successorResolved.route->crtcIds().front(), 45, 250);
+        CHECK(DIFFERENT_FIRST.disposition == eGroupedPageFlipDisposition::RECORDED);
+        const auto DIFFERENT_COMPLETION = authority.routePageFlip(5'010, successorResolved.route->crtcIds().back(), 46, 260);
+        CHECK(DIFFERENT_COMPLETION.disposition == eGroupedPageFlipDisposition::COMPLETED);
+        CHECK(DIFFERENT_COMPLETION.completionDelivered);
+        CHECK(DIFFERENT_COMPLETION.releasesDelivered == 1);
+        CHECK(publicationSink->releaseCount == 1);
+        CHECK(!currentBuffer->lockedByBackend);
+        CHECK(differentBuffer->lockedByBackend);
+        currentFramebuffer.reset();
+        currentBuffer.reset();
+
+        const auto stale = authority.routePageFlip(5'010, resolved.route->crtcIds().back(), 47, 270);
         CHECK(stale.claimed);
         CHECK(stale.disposition == eGroupedPageFlipDisposition::STALE);
-        CHECK(publicationSink->completions == 1);
+        CHECK(publicationSink->completions == 3);
 
         const auto QUIESCED = authority.quiesceAll(eTiledQuiesceReason::BACKEND_TEARDOWN);
         CHECK(!QUIESCED.invariantFailed);
diff --git a/tests/TiledDRMIntegration.cpp b/tests/TiledDRMIntegration.cpp
index 9aeb10295e6873aa25749764fa0d7d79a3526e6e..8462470deb7337795e8d432ddabe874660c73d72 100644
--- a/tests/TiledDRMIntegration.cpp
+++ b/tests/TiledDRMIntegration.cpp
@@ -660,8 +660,10 @@ int main() {
         EXPECT(TEST_MODESET.executionStatus.value_or(eTiledTestModesetStatus::INVALID_INPUT) == eTiledTestModesetStatus::SUCCEEDED, true);
         EXPECT(TEST_MODESET.submission.has_value(), true);
         EXPECT(TEST_MODESET.cleanup.complete(), true);
-        EXPECT(framebufferSource->acquisitions, 1U);
-        EXPECT(framebufferSource->sawExactDevice && framebufferSource->sawExactFD && framebufferSource->sawExactSize && framebufferSource->sawCommonPair, true);
+        // An exact caller-owned replacement already retains the validated FB;
+        // only the probe path acquires the authority scratch framebuffer.
+        EXPECT(framebufferSource->acquisitions, 0U);
+        EXPECT(framebufferSource->sawExactDevice || framebufferSource->sawExactFD || framebufferSource->sawExactSize || framebufferSource->sawCommonPair, false);
         EXPECT(atomicOperations->submits, 1U);
         EXPECT(atomicOperations->submittedFD, 73);
         EXPECT(atomicOperations->submittedFlags, TILED_ATOMIC_TEST_MODESET_FLAGS);