/* Copyright (c) 2019-2026 The Khronos Group Inc.
 * Copyright (c) 2019-2026 Valve Corporation
 * Copyright (c) 2019-2026 LunarG, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vulkan/utility/vk_format_utils.h>
#include "sync/sync_render_pass.h"
#include "sync/sync_validation.h"
#include "sync/sync_op.h"
#include "sync/sync_image.h"
#include "state_tracker/render_pass_state.h"
#include "state_tracker/pipeline_state.h"
#include "utils/math_utils.h"

namespace syncval {

class ValidateResolveAction {
  public:
    ValidateResolveAction(VkRenderPass render_pass, uint32_t subpass, uint32_t view_mask, const AccessContext& context,
                          const CommandBufferAccessContext& cb_context, vvl::Func command)
        : render_pass_(render_pass),
          subpass_(subpass),
          view_mask_(view_mask),
          context_(context),
          cb_context_(cb_context),
          command_(command),
          skip_(false) {}

    void operator()(const char* aspect_name, const char* resolve_action_name, uint32_t src_at, uint32_t dst_at,
                    const AttachmentViewGen& view_gen, AttachmentViewGen::Gen gen_type, SyncAccessIndex current_usage,
                    const AttachmentAccess& attachment_access) {
        const HazardResult hazard =
            context_.DetectAttachmentHazard(view_gen, gen_type, current_usage, attachment_access, view_mask_);
        if (hazard.IsHazard()) {
            const Location loc(command_);

            const SyncValidator& validator = cb_context_.GetSyncState();

            std::ostringstream ss;
            ss << validator.FormatHandle(view_gen.GetViewState()->Handle());
            ss << " (" << resolve_action_name << " of " << aspect_name << " multisample attachment " << src_at;
            ss << " in subpass " << subpass_ << " of " << validator.FormatHandle(render_pass_) << ")";
            const std::string resource_description = ss.str();
            const auto error =
                validator.error_messages_.RenderPassResolveError(hazard, cb_context_, command_, resource_description);
            skip_ |= validator.SyncError(hazard.Hazard(), render_pass_, loc, error);
        }
    }
    // Providing a mechanism for the constructing caller to get the result of the validation
    bool GetSkip() const { return skip_; }

  private:
    VkRenderPass render_pass_;
    const uint32_t subpass_;
    const uint32_t view_mask_;
    const AccessContext& context_;
    const CommandBufferAccessContext& cb_context_;
    vvl::Func command_;
    bool skip_;
};

class UpdateStateResolveAction {
  public:
    UpdateStateResolveAction(AccessContext& context, uint32_t view_mask, ResourceUsageTag tag)
        : context_(context), view_mask_(view_mask), tag_(tag) {}
    void operator()(const char*, const char*, uint32_t, uint32_t, const AttachmentViewGen& view_gen,
                    AttachmentViewGen::Gen gen_type, SyncAccessIndex current_usage, const AttachmentAccess& attachment_access) {
        context_.UpdateAttachmentAccessState(view_gen, gen_type, current_usage, attachment_access, ResourceUsageTagEx{tag_},
                                             view_mask_);
    }

  private:
    AccessContext& context_;
    const uint32_t view_mask_;
    const ResourceUsageTag tag_;
};

std::unique_ptr<AccessContext[]> InitSubpassContexts(VkQueueFlags queue_flags, const vvl::RenderPass& rp_state,
                                                     const AccessContext& external_context) {
    const uint32_t subpass_count = rp_state.create_info.subpassCount;
    auto subpass_contexts = std::make_unique<AccessContext[]>(subpass_count);
    // Add this for all subpasses here so that they exsist during next subpass validation
    for (uint32_t pass = 0; pass < subpass_count; pass++) {
        subpass_contexts[pass].validator = external_context.validator;
        subpass_contexts[pass].InitFrom(pass, queue_flags, rp_state.subpass_dependency_infos, subpass_contexts.get(),
                                        external_context);
    }
    return subpass_contexts;
}

static SyncAccessIndex GetLoadOpUsageIndex(VkAttachmentLoadOp load_op, AttachmentType type) {
    SyncAccessIndex access_index;
    if (load_op == VK_ATTACHMENT_LOAD_OP_NONE) {
        access_index = SYNC_ACCESS_INDEX_NONE;
    } else if (type == AttachmentType::kColor) {
        access_index = (load_op == VK_ATTACHMENT_LOAD_OP_LOAD) ? SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_READ
                                                               : SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE;
    } else {  // depth and stencil ops are the same
        access_index = (load_op == VK_ATTACHMENT_LOAD_OP_LOAD) ? SYNC_EARLY_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_READ
                                                               : SYNC_EARLY_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE;
    }
    return access_index;
}

static SyncAccessIndex GetStoreOpUsageIndex(VkAttachmentStoreOp store_op, AttachmentType type) {
    SyncAccessIndex access_index;
    if (store_op == VK_ATTACHMENT_STORE_OP_NONE) {
        access_index = SYNC_ACCESS_INDEX_NONE;
    } else if (type == AttachmentType::kColor) {
        access_index = SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE;
    } else {  // depth and stencil ops are the same
        access_index = SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE;
    }
    return access_index;
}

static SyncAccessIndex ColorLoadUsage(VkAttachmentLoadOp load_op) { return GetLoadOpUsageIndex(load_op, AttachmentType::kColor); }
static SyncAccessIndex DepthStencilLoadUsage(VkAttachmentLoadOp load_op) {
    return GetLoadOpUsageIndex(load_op, AttachmentType::kDepth);
}

// Keeps only those bits in view_mask for which subpass is "enabled" based on subpass_per_view.
static std::optional<uint32_t> FilterViewMask(uint32_t view_mask, uint32_t subpass,
                                              const vvl::RenderPass::SubpassPerView& subpass_per_view) {
    // Special case when multiview is disabled to unify caller code
    if (view_mask == 0) {
        return (subpass_per_view[0] == subpass) ? std::optional<uint32_t>(0) : std::nullopt;
    }

    uint32_t filtered_view_mask = 0;
    const auto view_indices = GetSetBitIndices(view_mask);
    for (uint8_t view_index : view_indices) {
        if (subpass_per_view[view_index] == subpass) {
            filtered_view_mask |= 1 << view_index;
        }
    }
    return (filtered_view_mask != 0) ? std::optional<uint32_t>(filtered_view_mask) : std::nullopt;
}

// Caller must manage returned pointer
static AccessContext* CreateStoreResolveProxyContext(const AccessContext& context, const vvl::RenderPass& rp_state,
                                                     uint32_t render_pass_instance_id, uint32_t subpass, uint32_t view_mask,
                                                     const AttachmentViewGenVector& attachment_views) {
    auto* proxy = new AccessContext(*context.validator);
    proxy->InitFrom(context);
    RenderPassAccessContext::UpdateAttachmentResolveAccess(rp_state, attachment_views, render_pass_instance_id, subpass, view_mask,
                                                           kInvalidTag, *proxy);
    RenderPassAccessContext::UpdateAttachmentStoreAccess(rp_state, attachment_views, render_pass_instance_id, subpass, view_mask,
                                                         kInvalidTag, *proxy);
    return proxy;
}

// Layout transitions are handled as if the were occuring in the beginning of the next subpass
bool RenderPassAccessContext::ValidateLayoutTransitions(const CommandBufferAccessContext& cb_context,
                                                        const AccessContext& access_context, const vvl::RenderPass& rp_state,
                                                        const VkRect2D& render_area, uint32_t render_pass_instance_id,
                                                        uint32_t subpass, uint32_t view_mask,
                                                        const AttachmentViewGenVector& attachment_views, vvl::Func command) {
    bool skip = false;
    // As validation methods are const and precede the record/update phase, for any tranistions from the immediately
    // previous subpass, we have to validate them against a copy of the AccessContext, with resolve operations applied, as
    // those affects have not been recorded yet.
    //
    // Note: we could be more efficient by tracking whether or not we actually *have* any changes (e.g. attachment resolve)
    // to apply and only copy then, if this proves a hot spot.
    std::unique_ptr<AccessContext> src_context_proxy;
    SubpassBarrier proxy_subpass_barrier;

    const auto& transitions = rp_state.subpass_transitions[subpass];
    for (const auto& transition : transitions) {
        const SubpassBarrier& subpass_barrier = access_context.GetSubpassBarrier(transition.src_subpass);
        const SubpassBarrier* p_subpass_barrier = &subpass_barrier;

        const bool src_context_needs_proxy =
            transition.src_subpass != VK_SUBPASS_EXTERNAL && (transition.src_subpass + 1 == subpass);

        if (src_context_needs_proxy) {
            if (!src_context_proxy) {
                // TODO: this looks wrong to create proxy once for all iterations.
                // Proxy depends on current iteration (transition.src_subpass), so it should be recreated
                // each time when needed. Write a test that exposes this and make a fix.
                src_context_proxy.reset(CreateStoreResolveProxyContext(*subpass_barrier.src_subpass_context, rp_state,
                                                                       render_pass_instance_id, transition.src_subpass, view_mask,
                                                                       attachment_views));
                proxy_subpass_barrier = subpass_barrier;
                proxy_subpass_barrier.src_subpass_context = src_context_proxy.get();
            }
            p_subpass_barrier = &proxy_subpass_barrier;
        }
        auto hazard = access_context.DetectSubpassTransitionHazard(*p_subpass_barrier, attachment_views[transition.attachment]);
        if (hazard.IsHazard()) {
            const SyncValidator& sync_state = cb_context.GetSyncState();
            const Location loc(command);

            const vvl::ImageView* attachment_view = attachment_views[transition.attachment].GetViewState();
            std::ostringstream ss;
            ss << "in subpass " << subpass << " of " << sync_state.FormatHandle(rp_state.Handle());
            ss << " on attachment " << transition.attachment << " (";
            ss << sync_state.FormatHandle(attachment_view->Handle());
            ss << ", " << sync_state.FormatHandle(attachment_view->image_state->Handle());
            ss << ", oldLayout " << string_VkImageLayout(transition.old_layout);
            ss << ", newLayout " << string_VkImageLayout(transition.new_layout);
            ss << ")";
            const std::string resource_description = ss.str();

            if (hazard.Tag() == kInvalidTag) {
                const auto error = sync_state.error_messages_.RenderPassLayoutTransitionVsResolveError(
                    hazard, cb_context, command, resource_description, transition.old_layout, transition.new_layout,
                    transition.src_subpass);
                skip |= sync_state.SyncError(hazard.Hazard(), rp_state.Handle(), loc, error);
            } else {
                const auto error = sync_state.error_messages_.RenderPassLayoutTransitionError(
                    hazard, cb_context, command, resource_description, transition.old_layout, transition.new_layout);
                skip |= sync_state.SyncError(hazard.Hazard(), rp_state.Handle(), loc, error);
            }
        }
    }
    return skip;
}

bool RenderPassAccessContext::ValidateLoadOperation(const CommandBufferAccessContext& cb_context,
                                                    const AccessContext& access_context, const vvl::RenderPass& rp_state,
                                                    const VkRect2D& render_area, uint32_t render_pass_instance_id, uint32_t subpass,
                                                    uint32_t view_mask, const AttachmentViewGenVector& attachment_views,
                                                    vvl::Func command) {
    bool skip = false;

    AttachmentAccess attachment_access;
    attachment_access.type = AttachmentAccessType::LoadOp;
    attachment_access.render_pass_instance_id = render_pass_instance_id;
    attachment_access.subpass = subpass;

    for (uint32_t i = 0; i < rp_state.create_info.attachmentCount; i++) {
        if (auto filtered_view_mask = FilterViewMask(view_mask, subpass, rp_state.attachment_first_subpass[i])) {
            const auto& view_gen = attachment_views[i];
            const auto& ci = rp_state.create_info.pAttachments[i];

            // Need check in the following way
            // 1) if the usage bit isn't in the dest_access_scope, and there is layout traniition for initial use, report hazard
            //    vs. transition
            // 2) if there isn't a layout transition, we need to look at the  external context with a "detect hazard" operation
            //    for each aspect loaded.

            const bool has_depth = vkuFormatHasDepth(ci.format);
            const bool has_stencil = vkuFormatHasStencil(ci.format);
            const bool is_color = !(has_depth || has_stencil);

            const SyncAccessIndex load_index = has_depth ? DepthStencilLoadUsage(ci.loadOp) : ColorLoadUsage(ci.loadOp);
            const SyncAccessIndex stencil_load_index = has_stencil ? DepthStencilLoadUsage(ci.stencilLoadOp) : load_index;

            HazardResult hazard;
            const char* aspect = nullptr;

            bool checked_stencil = false;
            if (is_color && (load_index != SYNC_ACCESS_INDEX_NONE)) {
                attachment_access.ordering = SyncOrdering::kColorAttachment;
                hazard = access_context.DetectAttachmentHazard(view_gen, AttachmentViewGen::Gen::kRenderArea, load_index,
                                                               attachment_access, *filtered_view_mask);
                aspect = "color";
            } else {
                if (has_depth && (load_index != SYNC_ACCESS_INDEX_NONE)) {
                    attachment_access.ordering = SyncOrdering::kDepthStencilAttachment;
                    hazard = access_context.DetectAttachmentHazard(view_gen, AttachmentViewGen::Gen::kDepthOnlyRenderArea,
                                                                   load_index, attachment_access, *filtered_view_mask);
                    aspect = "depth";
                }
                if (!hazard.IsHazard() && has_stencil && (stencil_load_index != SYNC_ACCESS_INDEX_NONE)) {
                    attachment_access.ordering = SyncOrdering::kDepthStencilAttachment;
                    hazard = access_context.DetectAttachmentHazard(view_gen, AttachmentViewGen::Gen::kStencilOnlyRenderArea,
                                                                   stencil_load_index, attachment_access, *filtered_view_mask);
                    aspect = "stencil";
                    checked_stencil = true;
                }
            }

            if (hazard.IsHazard()) {
                const VkAttachmentLoadOp load_op = checked_stencil ? ci.stencilLoadOp : ci.loadOp;
                const SyncValidator& sync_state = cb_context.GetSyncState();
                const Location loc(command);

                std::ostringstream ss;
                ss << "the " << aspect << " aspect of attachment " << i;
                ss << " (" << sync_state.FormatHandle(view_gen.GetViewState()->Handle()) << ")";
                ss << " in subpass " << subpass;
                ss << " of " << sync_state.FormatHandle(rp_state.Handle());
                ss << " (loadOp " << string_VkAttachmentLoadOp(load_op) << ")";
                const std::string resource_description = ss.str();

                if (hazard.Tag() == kInvalidTag) {  // Hazard vs. ILT
                    const auto error = sync_state.error_messages_.RenderPassLoadOpVsLayoutTransitionError(
                        hazard, cb_context, command, resource_description, load_op, is_color);
                    skip |= sync_state.SyncError(hazard.Hazard(), rp_state.Handle(), loc, error);
                } else {
                    const std::string error = sync_state.error_messages_.RenderPassLoadOpError(
                        hazard, cb_context, command, resource_description, subpass, i, load_op, is_color);
                    skip |= sync_state.SyncError(hazard.Hazard(), rp_state.Handle(), loc, error);
                }
            }
        }
    }
    return skip;
}

// Store operation validation can ignore resolve (before it) and layout tranistions after it.  The first is ignored
// because of the ordering guarantees w.r.t. sample access and that the resolve validation hasn't altered the state, because
// store is part of the same Next/End operation.
// The latter is handled in layout transistion validation directly
bool RenderPassAccessContext::ValidateStoreOperation(const CommandBufferAccessContext& cb_context, vvl::Func command) const {
    bool skip = false;

    const AttachmentAccess attachment_access = GetAttachmentAccess(SyncOrdering::kRaster, AttachmentAccessType::StoreOp);
    const uint32_t view_mask = rp_state_->create_info.pSubpasses[current_subpass_].viewMask;

    for (uint32_t i = 0; i < rp_state_->create_info.attachmentCount; i++) {
        if (auto filtered_view_mask = FilterViewMask(view_mask, current_subpass_, rp_state_->attachment_last_subpass[i])) {
            const AttachmentViewGen& view_gen = attachment_views_[i];
            const auto& ci = rp_state_->create_info.pAttachments[i];

            // The spec states that "don't care" is an operation with VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
            // so we assume that an implementation is *free* to write in that case, meaning that for correctness
            // sake, we treat DONT_CARE as writing.
            const bool has_depth = vkuFormatHasDepth(ci.format);
            const bool has_stencil = vkuFormatHasStencil(ci.format);
            const bool is_color = !(has_depth || has_stencil);
            const bool store_op_stores = ci.storeOp != VK_ATTACHMENT_STORE_OP_NONE;
            if (!has_stencil && !store_op_stores) continue;

            HazardResult hazard;
            const char* aspect = nullptr;
            bool checked_stencil = false;
            if (is_color) {
                hazard = CurrentContext().DetectAttachmentHazard(view_gen, AttachmentViewGen::Gen::kRenderArea,
                                                                 SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE,
                                                                 attachment_access, *filtered_view_mask);
                aspect = "color";
            } else {
                const bool stencil_op_stores = ci.stencilStoreOp != VK_ATTACHMENT_STORE_OP_NONE;
                if (has_depth && store_op_stores) {
                    hazard = CurrentContext().DetectAttachmentHazard(view_gen, AttachmentViewGen::Gen::kDepthOnlyRenderArea,
                                                                     SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE,
                                                                     attachment_access, *filtered_view_mask);
                    aspect = "depth";
                }
                if (!hazard.IsHazard() && has_stencil && stencil_op_stores) {
                    hazard = CurrentContext().DetectAttachmentHazard(view_gen, AttachmentViewGen::Gen::kStencilOnlyRenderArea,
                                                                     SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE,
                                                                     attachment_access, *filtered_view_mask);
                    aspect = "stencil";
                    checked_stencil = true;
                }
            }

            if (hazard.IsHazard()) {
                const SyncValidator& sync_state = cb_context.GetSyncState();
                const char* const op_type_string = checked_stencil ? "stencilStoreOp" : "storeOp";
                const VkAttachmentStoreOp store_op = checked_stencil ? ci.stencilStoreOp : ci.storeOp;
                const Location loc(command);

                std::ostringstream ss;
                ss << sync_state.FormatHandle(view_gen.GetViewState()->Handle());
                ss << " (subpass " << current_subpass_ << " of " << sync_state.FormatHandle(rp_state_->Handle());
                ss << ", attachment " << i;
                ss << ", aspect " << aspect << " during store with " << op_type_string;
                ss << " " << string_VkAttachmentStoreOp(store_op) << ")";
                const std::string resource_description = ss.str();

                const std::string error =
                    sync_state.error_messages_.RenderPassStoreOpError(hazard, cb_context, command, resource_description, store_op);
                skip |= sync_state.SyncError(hazard.Hazard(), rp_state_->Handle(), loc, error);
            }
        }
    }
    return skip;
}

static bool IsDepthAttachmentWriteable(const LastBound& last_bound_state, const VkFormat format) {
    const bool depth_write_enable = last_bound_state.IsDepthWriteEnable();
    return (vkuFormatIsDepthAndStencil(format) || vkuFormatIsDepthOnly(format)) && depth_write_enable;
}

static bool IsStencilAttachmentWriteable(const LastBound& last_bound_state, const VkFormat format) {
    if (!vkuFormatIsDepthAndStencil(format) && !vkuFormatIsStencilOnly(format)) {
        return false;
    }
    if (!last_bound_state.IsStencilTestEnable()) {
        return false;
    }
    auto is_writable = [&last_bound_state](const VkStencilOpState& ops) -> bool {
        if (ops.writeMask == 0) {
            return false;
        }

        // If compareOp is ALWAYS then failOp never runs (no writes possible)
        const bool ignore_fail_op = (ops.compareOp == VK_COMPARE_OP_ALWAYS);

        // If compareOp is NEVER then passOp never runs (no writes possible)
        const bool ignore_pass_op = (ops.compareOp == VK_COMPARE_OP_NEVER);

        // If depth test is not enabled then depthFailOp never runs (no writes possible)
        const bool ignore_depth_fail_op = !last_bound_state.IsDepthTestEnable();

        const bool is_read = (ops.failOp == VK_STENCIL_OP_KEEP || ignore_fail_op) &&
                             (ops.passOp == VK_STENCIL_OP_KEEP || ignore_pass_op) &&
                             (ops.depthFailOp == VK_STENCIL_OP_KEEP || ignore_depth_fail_op);
        return !is_read;
    };
    const VkStencilOpState front_ops = last_bound_state.GetStencilOpStateFront();
    const VkStencilOpState back_ops = last_bound_state.GetStencilOpStateBack();
    return is_writable(front_ops) || is_writable(back_ops);
}

// Traverse the attachment resolves for this a specific subpass, and do action() to them.
// Used by both validation and record operations
//
// The signature for Action() reflect the needs of both uses.
template <typename Action>
void ResolveOperation(Action& action, const vvl::RenderPass& rp_state, const AttachmentViewGenVector& attachment_views,
                      uint32_t render_pass_instance_id, uint32_t subpass) {
    const auto& rp_ci = rp_state.create_info;
    const auto* attachment_ci = rp_ci.pAttachments;
    const auto& subpass_ci = rp_ci.pSubpasses[subpass];

    AttachmentAccess attachment_access;
    attachment_access.render_pass_instance_id = render_pass_instance_id;
    attachment_access.subpass = subpass;

    // Color resolve requires an inuse color attachment and a matching inuse resolve attachment
    if (subpass_ci.pResolveAttachments && subpass_ci.pColorAttachments) {
        attachment_access.ordering = SyncOrdering::kColorAttachment;
        for (uint32_t i = 0; i < subpass_ci.colorAttachmentCount; i++) {
            const uint32_t color_attach = subpass_ci.pColorAttachments[i].attachment;
            const uint32_t resolve_attach = subpass_ci.pResolveAttachments[i].attachment;
            if (color_attach != VK_ATTACHMENT_UNUSED && resolve_attach != VK_ATTACHMENT_UNUSED) {
                attachment_access.type = AttachmentAccessType::ResolveRead;
                action("color", "resolve read", color_attach, resolve_attach, attachment_views[color_attach],
                       AttachmentViewGen::Gen::kRenderArea, SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_READ, attachment_access);

                attachment_access.type = AttachmentAccessType::ResolveWrite;
                action("color", "resolve write", color_attach, resolve_attach, attachment_views[resolve_attach],
                       AttachmentViewGen::Gen::kRenderArea, SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE, attachment_access);
            }
        }
    }

    // Depth stencil resolve only if the extension is present
    const auto ds_resolve = vku::FindStructInPNextChain<VkSubpassDescriptionDepthStencilResolve>(subpass_ci.pNext);
    if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment &&
        (ds_resolve->pDepthStencilResolveAttachment->attachment != VK_ATTACHMENT_UNUSED) && subpass_ci.pDepthStencilAttachment &&
        (subpass_ci.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
        const auto src_at = subpass_ci.pDepthStencilAttachment->attachment;
        const auto src_ci = attachment_ci[src_at];
        // The formats are required to match so we can pick either
        const bool resolve_depth = (ds_resolve->depthResolveMode != VK_RESOLVE_MODE_NONE) && vkuFormatHasDepth(src_ci.format);
        const bool resolve_stencil = (ds_resolve->stencilResolveMode != VK_RESOLVE_MODE_NONE) && vkuFormatHasStencil(src_ci.format);
        const auto dst_at = ds_resolve->pDepthStencilResolveAttachment->attachment;

        // Figure out which aspects are actually touched during resolve operations
        const char* aspect_string = nullptr;
        AttachmentViewGen::Gen gen_type = AttachmentViewGen::Gen::kRenderArea;
        if (resolve_depth && resolve_stencil) {
            aspect_string = "depth/stencil";
        } else if (resolve_depth) {
            // Validate depth only
            gen_type = AttachmentViewGen::Gen::kDepthOnlyRenderArea;
            aspect_string = "depth";
        } else if (resolve_stencil) {
            // Validate all stencil only
            gen_type = AttachmentViewGen::Gen::kStencilOnlyRenderArea;
            aspect_string = "stencil";
        }

        if (aspect_string) {
            attachment_access.ordering = SyncOrdering::kRaster;

            attachment_access.type = AttachmentAccessType::ResolveRead;
            action(aspect_string, "resolve read", src_at, dst_at, attachment_views[src_at], gen_type,
                   SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_READ, attachment_access);

            attachment_access.type = AttachmentAccessType::ResolveWrite;
            action(aspect_string, "resolve write", src_at, dst_at, attachment_views[dst_at], gen_type,
                   SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE, attachment_access);
        }
    }
}

bool RenderPassAccessContext::ValidateResolveOperations(const CommandBufferAccessContext& cb_context, vvl::Func command) const {
    const uint32_t view_mask = rp_state_->create_info.pSubpasses[current_subpass_].viewMask;
    ValidateResolveAction validate_action(rp_state_->VkHandle(), current_subpass_, view_mask, CurrentContext(), cb_context,
                                          command);
    ResolveOperation(validate_action, *rp_state_, attachment_views_, render_pass_instance_id_, current_subpass_);
    return validate_action.GetSkip();
}

void RenderPassAccessContext::UpdateAttachmentResolveAccess(const vvl::RenderPass& rp_state,
                                                            const AttachmentViewGenVector& attachment_views,
                                                            uint32_t render_pass_instance_id, uint32_t subpass, uint32_t view_mask,
                                                            const ResourceUsageTag tag, AccessContext& access_context) {
    UpdateStateResolveAction update(access_context, view_mask, tag);
    ResolveOperation(update, rp_state, attachment_views, render_pass_instance_id, subpass);
}

void RenderPassAccessContext::UpdateAttachmentStoreAccess(const vvl::RenderPass& rp_state,
                                                          const AttachmentViewGenVector& attachment_views,
                                                          uint32_t render_pass_instance_id, uint32_t subpass, uint32_t view_mask,
                                                          const ResourceUsageTag tag, AccessContext& access_context) {
    AttachmentAccess attachment_access;
    attachment_access.type = AttachmentAccessType::StoreOp;
    attachment_access.ordering = SyncOrdering::kRaster;
    attachment_access.render_pass_instance_id = render_pass_instance_id;
    attachment_access.subpass = subpass;

    for (uint32_t i = 0; i < rp_state.create_info.attachmentCount; i++) {
        if (auto filtered_view_mask = FilterViewMask(view_mask, subpass, rp_state.attachment_last_subpass[i])) {
            const auto& view_gen = attachment_views[i];

            const auto& ci = rp_state.create_info.pAttachments[i];
            const bool has_depth = vkuFormatHasDepth(ci.format);
            const bool has_stencil = vkuFormatHasStencil(ci.format);
            const bool is_color = !(has_depth || has_stencil);
            const bool store_op_stores = ci.storeOp != VK_ATTACHMENT_STORE_OP_NONE;

            if (is_color && store_op_stores) {
                access_context.UpdateAttachmentAccessState(view_gen, AttachmentViewGen::Gen::kRenderArea,
                                                           SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE, attachment_access,
                                                           ResourceUsageTagEx{tag}, *filtered_view_mask);
            } else {
                if (has_depth && store_op_stores) {
                    access_context.UpdateAttachmentAccessState(view_gen, AttachmentViewGen::Gen::kDepthOnlyRenderArea,
                                                               SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE,
                                                               attachment_access, ResourceUsageTagEx{tag}, *filtered_view_mask);
                }
                const bool stencil_op_stores = ci.stencilStoreOp != VK_ATTACHMENT_STORE_OP_NONE;
                if (has_stencil && stencil_op_stores) {
                    access_context.UpdateAttachmentAccessState(view_gen, AttachmentViewGen::Gen::kStencilOnlyRenderArea,
                                                               SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE,
                                                               attachment_access, ResourceUsageTagEx{tag}, *filtered_view_mask);
                }
            }
        }
    }
}

void RenderPassAccessContext::RecordLayoutTransitions(const vvl::RenderPass& rp_state, uint32_t subpass,
                                                      const AttachmentViewGenVector& attachment_views, const ResourceUsageTag tag,
                                                      AccessContext& access_context) {
    const auto& transitions = rp_state.subpass_transitions[subpass];
    for (const auto& transition : transitions) {
        const auto& view_gen = attachment_views[transition.attachment];
        const SubpassBarrier& subpass_barrier = access_context.GetSubpassBarrier(transition.src_subpass);
        const AccessContext& src_subpass_context = *subpass_barrier.src_subpass_context;

        // Import the attachments into the current context
        ApplySubpassTransitionBarrierAction barrier_action(subpass_barrier, tag);
        ImageRangeGen attachment_gen = view_gen.GetRangeGen(AttachmentViewGen::Gen::kViewSubresource);
        access_context.ResolveFromSubpassContext(barrier_action, src_subpass_context, attachment_gen);
    }
}

bool RenderPassAccessContext::ValidateDrawSubpassAttachment(const CommandBufferAccessContext& cb_context, vvl::Func command) const {
    bool skip = false;
    const vvl::CommandBuffer& cmd_buffer = cb_context.GetCBState();
    const auto& last_bound_state = cmd_buffer.GetLastBoundGraphics();
    const auto* pipe = last_bound_state.pipeline_state;

    if (!pipe || pipe->RasterizationDisabled()) {
        return skip;
    }

    const auto& list = pipe->fs_writable_output_location_list;
    const auto& subpass = rp_state_->create_info.pSubpasses[current_subpass_];
    const auto& current_context = CurrentContext();
    const SyncValidator& sync_state = cb_context.GetSyncState();

    auto report_atachment_hazard = [&sync_state, &cb_context, command](const HazardResult& hazard,
                                                                       const vvl::ImageView& attachment_view,
                                                                       std::string_view attachment_description) {
        const vvl::Image& attachment_image = *attachment_view.image_state;
        LogObjectList objlist(cb_context.GetCBState().Handle(), attachment_view.Handle(), attachment_image.Handle());
        const Location loc(command);

        std::ostringstream ss;
        ss << attachment_description;
        ss << " (" << sync_state.FormatHandle(attachment_view.Handle());
        ss << ", " << sync_state.FormatHandle(attachment_image.Handle()) << ")";
        const std::string resource_description = ss.str();

        const std::string error =
            sync_state.error_messages_.RenderPassAttachmentError(hazard, cb_context, command, resource_description);
        return sync_state.SyncError(hazard.Hazard(), objlist, loc, error);
    };

    // Subpass's inputAttachment has been done in ValidateDispatchDrawDescriptorSet
    if (subpass.pColorAttachments && subpass.colorAttachmentCount && !list.empty()) {
        for (const auto location : list) {
            if (location >= subpass.colorAttachmentCount ||
                subpass.pColorAttachments[location].attachment == VK_ATTACHMENT_UNUSED) {
                continue;
            }
            const AttachmentAccess attachment_access = GetAttachmentAccess(SyncOrdering::kColorAttachment);
            const AttachmentViewGen& view_gen = attachment_views_[subpass.pColorAttachments[location].attachment];
            HazardResult hazard = current_context.DetectAttachmentHazard(view_gen, AttachmentViewGen::Gen::kRenderArea,
                                                                         SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE,
                                                                         attachment_access, subpass.viewMask);
            if (hazard.IsHazard()) {
                std::ostringstream ss;
                ss << "color attachment " << location << " in subpass " << cmd_buffer.GetActiveSubpass();
                const std::string attachment_description = ss.str();
                skip |= report_atachment_hazard(hazard, *view_gen.GetViewState(), attachment_description);
            }
        }
    }

    // PHASE1 TODO: Read operations for both depth and stencil are possible in the future.
    const auto ds_state = pipe->DepthStencilState();
    const uint32_t depth_stencil_attachment = GetSubpassDepthStencilAttachmentIndex(ds_state, subpass.pDepthStencilAttachment);

    if (depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
        const AttachmentViewGen& view_gen = attachment_views_[depth_stencil_attachment];
        const vvl::ImageView& view_state = *view_gen.GetViewState();
        const VkFormat ds_format = view_state.create_info.format;
        const bool depth_write = IsDepthAttachmentWriteable(last_bound_state, ds_format);
        const bool stencil_write = IsStencilAttachmentWriteable(last_bound_state, ds_format);

        if (depth_write) {
            const AttachmentAccess attachment_access = GetAttachmentAccess(SyncOrdering::kDepthStencilAttachment);
            HazardResult hazard = current_context.DetectAttachmentHazard(view_gen, AttachmentViewGen::Gen::kDepthOnlyRenderArea,
                                                                         SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE,
                                                                         attachment_access, subpass.viewMask);
            if (hazard.IsHazard()) {
                std::ostringstream ss;
                ss << "depth aspect of depth-stencil attachment  in subpass " << cmd_buffer.GetActiveSubpass();
                const std::string attachment_description = ss.str();
                skip |= report_atachment_hazard(hazard, view_state, attachment_description);
            }
        }
        if (stencil_write) {
            const AttachmentAccess attachment_access = GetAttachmentAccess(SyncOrdering::kDepthStencilAttachment);
            HazardResult hazard = current_context.DetectAttachmentHazard(view_gen, AttachmentViewGen::Gen::kStencilOnlyRenderArea,
                                                                         SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE,
                                                                         attachment_access, subpass.viewMask);
            if (hazard.IsHazard()) {
                std::ostringstream ss;
                ss << "stencil aspect of depth-stencil attachment  in subpass " << cmd_buffer.GetActiveSubpass();
                const std::string attachment_description = ss.str();
                skip |= report_atachment_hazard(hazard, view_state, attachment_description);
            }
        }
    }
    return skip;
}

void RenderPassAccessContext::RecordDrawSubpassAttachment(const vvl::CommandBuffer& cmd_buffer, const ResourceUsageTag tag) {
    const auto& last_bound_state = cmd_buffer.GetLastBoundGraphics();
    const auto* pipe = last_bound_state.pipeline_state;
    if (!pipe || pipe->RasterizationDisabled()) {
        return;
    }

    const auto& list = pipe->fs_writable_output_location_list;
    const auto& subpass = rp_state_->create_info.pSubpasses[current_subpass_];

    auto& current_context = CurrentContext();
    // Subpass's inputAttachment has been done in RecordDispatchDrawDescriptorSet
    if (subpass.pColorAttachments && subpass.colorAttachmentCount && !list.empty()) {
        for (const auto location : list) {
            if (location >= subpass.colorAttachmentCount ||
                subpass.pColorAttachments[location].attachment == VK_ATTACHMENT_UNUSED) {
                continue;
            }
            const AttachmentAccess attachment_access = GetAttachmentAccess(SyncOrdering::kColorAttachment);
            const AttachmentViewGen& view_gen = attachment_views_[subpass.pColorAttachments[location].attachment];
            current_context.UpdateAttachmentAccessState(view_gen, AttachmentViewGen::Gen::kRenderArea,
                                                        SYNC_COLOR_ATTACHMENT_OUTPUT_COLOR_ATTACHMENT_WRITE, attachment_access,
                                                        ResourceUsageTagEx{tag}, subpass.viewMask);
        }
    }

    // PHASE1 TODO: Read operations for both depth and stencil are possible in the future.
    const auto* ds_state = pipe->DepthStencilState();
    const uint32_t depth_stencil_attachment = GetSubpassDepthStencilAttachmentIndex(ds_state, subpass.pDepthStencilAttachment);
    if (depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
        const AttachmentViewGen& view_gen = attachment_views_[depth_stencil_attachment];
        const vvl::ImageView& view_state = *view_gen.GetViewState();
        const VkFormat ds_format = view_state.create_info.format;
        const bool depth_write = IsDepthAttachmentWriteable(last_bound_state, ds_format);
        const bool stencil_write = IsStencilAttachmentWriteable(last_bound_state, ds_format);

        if (depth_write || stencil_write) {
            const AttachmentAccess attachment_access = GetAttachmentAccess(SyncOrdering::kDepthStencilAttachment);
            const auto ds_gentype = view_gen.GetDepthStencilRenderAreaGenType(depth_write, stencil_write);
            current_context.UpdateAttachmentAccessState(view_gen, ds_gentype,
                                                        SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE, attachment_access,
                                                        ResourceUsageTagEx{tag}, subpass.viewMask);
        }
    }
}

const vvl::ImageView* RenderPassAccessContext::GetClearAttachmentView(const VkClearAttachment& clear_attachment) const {
    const auto& subpass = rp_state_->create_info.pSubpasses[current_subpass_];
    uint32_t attachment_index = VK_ATTACHMENT_UNUSED;
    if (clear_attachment.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
        if (clear_attachment.colorAttachment < subpass.colorAttachmentCount) {
            attachment_index = subpass.pColorAttachments[clear_attachment.colorAttachment].attachment;
        }
    } else if (clear_attachment.aspectMask & kDepthStencilAspects) {
        if (subpass.pDepthStencilAttachment) {
            attachment_index = subpass.pDepthStencilAttachment->attachment;
        }
    }
    // This catches both out of bounds attachment index and VK_ATTACHMENT_UNUSED special value.
    if (attachment_index >= rp_state_->create_info.attachmentCount) {
        return nullptr;
    }
    return attachment_views_[attachment_index].GetViewState();
}

bool RenderPassAccessContext::ValidateNextSubpass(const CommandBufferAccessContext& cb_context, vvl::Func command) const {
    // PHASE1 TODO: Add Validate Preserve attachments
    bool skip = false;
    skip |= ValidateResolveOperations(cb_context, command);
    skip |= ValidateStoreOperation(cb_context, command);

    const auto next_subpass = current_subpass_ + 1;
    if (next_subpass >= rp_state_->create_info.subpassCount) {
        return skip;
    }
    const uint32_t next_subpass_view_mask = rp_state_->create_info.pSubpasses[next_subpass].viewMask;
    const auto& next_context = subpass_contexts_[next_subpass];
    skip |= ValidateLayoutTransitions(cb_context, next_context, *rp_state_, render_area_, render_pass_instance_id_, next_subpass,
                                      next_subpass_view_mask, attachment_views_, command);
    if (!skip) {
        // To avoid complex (and buggy) duplication of the affect of layout transitions on load operations, we'll record them
        // on a copy of the (empty) next context.
        // Note: The resource access map should be empty so hopefully this copy isn't too horrible from a perf POV.
        AccessContext temp_context(cb_context.GetSyncState());
        temp_context.InitFrom(next_context);
        RecordLayoutTransitions(*rp_state_, next_subpass, attachment_views_, kInvalidTag, temp_context);
        skip |= ValidateLoadOperation(cb_context, temp_context, *rp_state_, render_area_, render_pass_instance_id_, next_subpass,
                                      next_subpass_view_mask, attachment_views_, command);
    }
    return skip;
}
bool RenderPassAccessContext::ValidateEndRenderPass(const CommandBufferAccessContext& cb_context, vvl::Func command) const {
    // PHASE1 TODO: Validate Preserve
    bool skip = false;
    skip |= ValidateResolveOperations(cb_context, command);
    skip |= ValidateStoreOperation(cb_context, command);
    skip |= ValidateFinalSubpassLayoutTransitions(cb_context, command);
    return skip;
}

AccessContext* RenderPassAccessContext::CreateStoreResolveProxy() const {
    return CreateStoreResolveProxyContext(CurrentContext(), *rp_state_, render_pass_instance_id_, current_subpass_,
                                          rp_state_->create_info.pSubpasses[current_subpass_].viewMask, attachment_views_);
}

bool RenderPassAccessContext::ValidateFinalSubpassLayoutTransitions(const CommandBufferAccessContext& cb_context,
                                                                    vvl::Func command) const {
    bool skip = false;

    // As validation methods are const and precede the record/update phase, for any tranistions from the current (last)
    // subpass, we have to validate them against a copy of the current AccessContext, with resolve operations applied.
    // Note: we could be more efficient by tracking whether or not we actually *have* any changes (e.g. attachment resolve)
    // to apply and only copy then, if this proves a hot spot.
    std::unique_ptr<AccessContext> proxy_for_current;

    // Validate the "finalLayout" transitions to external
    // Get them from where there we're hidding in the extra entry.
    const auto& final_transitions = rp_state_->subpass_transitions.back();
    for (const auto& transition : final_transitions) {
        const auto& view_gen = attachment_views_[transition.attachment];
        const SubpassBarrier& subpass_barrier = subpass_contexts_[transition.src_subpass].GetDstExternalSubpassBarrier();
        const AccessContext* context = subpass_barrier.src_subpass_context;

        if (transition.src_subpass == current_subpass_) {
            if (!proxy_for_current) {
                // We haven't recorded resolve ofor the current_subpass, so we need to copy current and update it *as if*
                proxy_for_current.reset(CreateStoreResolveProxy());
            }
            context = proxy_for_current.get();
        }

        // Use the merged barrier for the hazard check (safe since it just considers the src (first) scope.
        const SyncBarrier merged_barrier(subpass_barrier.barriers);
        auto hazard = context->DetectImageBarrierHazard(view_gen, merged_barrier, AccessContext::DetectOptions::kDetectPrevious);
        if (hazard.IsHazard()) {
            const SyncValidator& sync_state = cb_context.GetSyncState();
            const Location loc(command);

            std::ostringstream ss;
            ss << "on attachment " << transition.attachment << " (";
            ss << sync_state.FormatHandle(view_gen.GetViewState()->Handle());
            ss << ", " << sync_state.FormatHandle(view_gen.GetViewState()->image_state->Handle());
            ss << ", oldLayout " << string_VkImageLayout(transition.old_layout);
            ss << ", newLayout " << string_VkImageLayout(transition.new_layout);
            ss << ")";
            const std::string resource_description = ss.str();

            if (hazard.Tag() == kInvalidTag) {  // Hazard vs. store/resolve
                const std::string error = sync_state.error_messages_.RenderPassFinalLayoutTransitionVsStoreOrResolveError(
                    hazard, cb_context, command, resource_description, transition.old_layout, transition.new_layout,
                    transition.src_subpass);
                skip |= sync_state.SyncError(hazard.Hazard(), rp_state_->Handle(), loc, error);
            } else {
                const std::string error = sync_state.error_messages_.RenderPassFinalLayoutTransitionError(
                    hazard, cb_context, command, resource_description, transition.old_layout, transition.new_layout);
                skip |= sync_state.SyncError(hazard.Hazard(), rp_state_->Handle(), loc, error);
            }
        }
    }
    return skip;
}

void RenderPassAccessContext::RecordLayoutTransitions(const ResourceUsageTag tag) {
    // Add layout transitions...
    RecordLayoutTransitions(*rp_state_, current_subpass_, attachment_views_, tag, CurrentContext());
}

void RenderPassAccessContext::RecordLoadOperations(const ResourceUsageTag tag) {
    const auto* attachment_ci = rp_state_->create_info.pAttachments;
    auto& subpass_context = CurrentContext();
    const uint32_t view_mask = rp_state_->create_info.pSubpasses[current_subpass_].viewMask;

    for (uint32_t i = 0; i < rp_state_->create_info.attachmentCount; i++) {
        if (auto filtered_view_mask = FilterViewMask(view_mask, current_subpass_, rp_state_->attachment_first_subpass[i])) {
            const AttachmentViewGen& view_gen = attachment_views_[i];

            const VkAttachmentDescription2& ci = *attachment_ci[i].ptr();
            const bool has_depth = vkuFormatHasDepth(ci.format);
            const bool has_stencil = vkuFormatHasStencil(ci.format);
            const bool is_color = !(has_depth || has_stencil);

            if (is_color) {
                // TODO: LoadOp can access the entire attachment subresource, not only the render area.
                // The exception is when a feedback loop is enabled for the attachment, then only the render area is accessed.
                const SyncAccessIndex load_op_access = ColorLoadUsage(ci.loadOp);
                if (load_op_access != SYNC_ACCESS_INDEX_NONE) {
                    const AttachmentAccess attachment_access =
                        GetAttachmentAccess(SyncOrdering::kColorAttachment, AttachmentAccessType::LoadOp);
                    subpass_context.UpdateAttachmentAccessState(view_gen, AttachmentViewGen::Gen::kRenderArea, load_op_access,
                                                                attachment_access, ResourceUsageTagEx{tag}, *filtered_view_mask);
                }
            } else {
                // TODO: Update depth/stencil aspects separately only if separateDepthStencilAttachmentAccess is defined,
                // otherwise both should be updated.
                // Also LoadOp can access the entire attachment subresource, not only the render area.
                // The exception is when a feedback loop is enabled for the attachment, then only the render area is accessed.
                const AttachmentAccess attachment_access =
                    GetAttachmentAccess(SyncOrdering::kDepthStencilAttachment, AttachmentAccessType::LoadOp);
                if (has_depth) {
                    const SyncAccessIndex load_op = DepthStencilLoadUsage(ci.loadOp);
                    if (load_op != SYNC_ACCESS_INDEX_NONE) {
                        subpass_context.UpdateAttachmentAccessState(view_gen, AttachmentViewGen::Gen::kDepthOnlyRenderArea, load_op,
                                                                    attachment_access, ResourceUsageTagEx{tag},
                                                                    *filtered_view_mask);
                    }
                }
                if (has_stencil) {
                    const SyncAccessIndex load_op = DepthStencilLoadUsage(ci.stencilLoadOp);
                    if (load_op != SYNC_ACCESS_INDEX_NONE) {
                        subpass_context.UpdateAttachmentAccessState(view_gen, AttachmentViewGen::Gen::kStencilOnlyRenderArea,
                                                                    load_op, attachment_access, ResourceUsageTagEx{tag},
                                                                    *filtered_view_mask);
                    }
                }
            }
        }
    }
}

AttachmentViewGenVector RenderPassAccessContext::CreateAttachmentViewGen(
    const VkRect2D& render_area, const std::vector<const vvl::ImageView*>& attachment_views) {
    AttachmentViewGenVector view_gens;
    VkExtent3D extent = CastTo3D(render_area.extent);
    VkOffset3D offset = CastTo3D(render_area.offset);
    view_gens.reserve(attachment_views.size());
    for (const auto* view : attachment_views) {
        view_gens.emplace_back(view, offset, extent);
    }
    return view_gens;
}

RenderPassAccessContext::RenderPassAccessContext(const vvl::RenderPass& rp_state, const VkRect2D& render_area,
                                                 VkQueueFlags queue_flags,
                                                 const std::vector<const vvl::ImageView*>& attachment_views,
                                                 const AccessContext& external_context, uint32_t render_pass_instance_id)
    : rp_state_(&rp_state),
      render_area_(render_area),
      attachment_views_(CreateAttachmentViewGen(render_area, attachment_views)),
      subpass_contexts_(InitSubpassContexts(queue_flags, rp_state, external_context)),
      render_pass_instance_id_(render_pass_instance_id),
      current_subpass_(0) {}

void RenderPassAccessContext::RecordBeginRenderPass(const ResourceUsageTag barrier_tag, const ResourceUsageTag load_tag) {
    assert(0 == current_subpass_);
    AccessContext& current_context = CurrentContext();
    current_context.SetStartTag(barrier_tag);

    RecordLayoutTransitions(barrier_tag);
    RecordLoadOperations(load_tag);
}

void RenderPassAccessContext::RecordNextSubpass(ResourceUsageTag resolve_tag, const ResourceUsageTag store_tag,
                                                const ResourceUsageTag transition_tag, const ResourceUsageTag load_tag) {
    const uint32_t view_mask = rp_state_->create_info.pSubpasses[current_subpass_].viewMask;

    // Resolves are against *prior* subpass context and thus *before* the subpass increment
    UpdateAttachmentResolveAccess(*rp_state_, attachment_views_, render_pass_instance_id_, current_subpass_, view_mask, resolve_tag,
                                  CurrentContext());
    UpdateAttachmentStoreAccess(*rp_state_, attachment_views_, render_pass_instance_id_, current_subpass_, view_mask, store_tag,
                                CurrentContext());

    if (current_subpass_ + 1 >= rp_state_->create_info.subpassCount) {
        return;
    }
    // Move to the next sub-command for the new subpass. The resolve and store are logically part of the previous
    // subpass, so their tag needs to be different from the layout and load operations below.
    current_subpass_++;
    AccessContext& current_context = CurrentContext();
    current_context.SetStartTag(transition_tag);

    RecordLayoutTransitions(transition_tag);
    RecordLoadOperations(load_tag);
}

void RenderPassAccessContext::RecordEndRenderPass(AccessContext* external_context, const ResourceUsageTag store_tag,
                                                  const ResourceUsageTag transition_tag) {
    const uint32_t view_mask = rp_state_->create_info.pSubpasses[current_subpass_].viewMask;

    // Add the resolve and store accesses
    UpdateAttachmentResolveAccess(*rp_state_, attachment_views_, render_pass_instance_id_, current_subpass_, view_mask, store_tag,
                                  CurrentContext());
    UpdateAttachmentStoreAccess(*rp_state_, attachment_views_, render_pass_instance_id_, current_subpass_, view_mask, store_tag,
                                CurrentContext());

    // Export the accesses from the renderpass...
    external_context->ResolveChildContexts(GetSubpassContexts());

    // Add the "finalLayout" transitions to external
    // Get them from where there we're hidding in the extra entry.
    // Not that since *final* always comes from *one* subpass per view, we don't have to accumulate the barriers
    // TODO Aliasing we may need to reconsider barrier accumulation... though I don't know that it would be valid for aliasing
    //      that had mulitple final layout transistions from mulitple final subpasses.
    const auto& final_transitions = rp_state_->subpass_transitions.back();
    for (const auto& transition : final_transitions) {
        const AttachmentViewGen& view_gen = attachment_views_[transition.attachment];
        const SubpassBarrier& dst_external_barrier = subpass_contexts_[transition.src_subpass].GetDstExternalSubpassBarrier();
        assert(&subpass_contexts_[transition.src_subpass] == dst_external_barrier.src_subpass_context);

        ImageRangeGen range_gen = view_gen.GetRangeGen(AttachmentViewGen::Gen::kViewSubresource);

        ImageRangeGen markup_range_gen = range_gen;  // second copy, preserve range_gen to use later
        ApplyMarkupFunctor markup_action(true);
        external_context->UpdateMemoryAccessState(markup_action, markup_range_gen);

        PendingBarriers pending_barriers;
        for (const auto& barrier : dst_external_barrier.barriers) {
            const BarrierScope barrier_scope(barrier);
            CollectBarriersFunctor collect_barriers(*external_context, barrier_scope, barrier, true, vvl::kNoIndex32,
                                                    pending_barriers);
            external_context->UpdateMemoryAccessState(collect_barriers, range_gen);
        }
        pending_barriers.Apply(transition_tag);
    }
}

AccessContext& RenderPassAccessContext::CurrentContext() {
    assert(current_subpass_ < rp_state_->create_info.subpassCount);
    return subpass_contexts_[current_subpass_];
}

const AccessContext& RenderPassAccessContext::CurrentContext() const {
    assert(current_subpass_ < rp_state_->create_info.subpassCount);
    return subpass_contexts_[current_subpass_];
}

vvl::span<const AccessContext> RenderPassAccessContext::GetSubpassContexts() const {
    return vvl::make_span<const AccessContext>(subpass_contexts_.get(), rp_state_->create_info.subpassCount);
}

vvl::span<AccessContext> RenderPassAccessContext::GetSubpassContexts() {
    return vvl::make_span<AccessContext>(subpass_contexts_.get(), rp_state_->create_info.subpassCount);
}

AttachmentAccess RenderPassAccessContext::GetAttachmentAccess(SyncOrdering ordering, AttachmentAccessType type) const {
    AttachmentAccess attachment_access;
    attachment_access.type = type;
    attachment_access.ordering = ordering;
    attachment_access.render_pass_instance_id = render_pass_instance_id_;
    attachment_access.subpass = current_subpass_;
    return attachment_access;
}

void BeginRenderingCmdState::AddRenderingInfo(const SyncValidator& state, const VkRenderingInfo& rendering_info) {
    info = std::make_unique<DynamicRenderingInfo>(state, rendering_info);
}

const DynamicRenderingInfo& BeginRenderingCmdState::GetRenderingInfo() const {
    assert(info);
    return *info;
}
DynamicRenderingInfo::DynamicRenderingInfo(const SyncValidator& state, const VkRenderingInfo& rendering_info)
    : info(&rendering_info) {
    uint32_t attachment_count = info.colorAttachmentCount + (info.pDepthAttachment ? 1 : 0) + (info.pStencilAttachment ? 1 : 0);

    const VkOffset3D offset = CastTo3D(info.renderArea.offset);
    const VkExtent3D extent = CastTo3D(info.renderArea.extent);

    attachments.reserve(attachment_count);
    for (uint32_t i = 0; i < info.colorAttachmentCount; i++) {
        attachments.emplace_back(state, info.pColorAttachments[i], AttachmentType::kColor, offset, extent);
    }

    if (info.pDepthAttachment) {
        attachments.emplace_back(state, *info.pDepthAttachment, AttachmentType::kDepth, offset, extent);
    }

    if (info.pStencilAttachment) {
        attachments.emplace_back(state, *info.pStencilAttachment, AttachmentType::kStencil, offset, extent);
    }
}

const vvl::ImageView* DynamicRenderingInfo::GetClearAttachmentView(const VkClearAttachment& clear_attachment) const {
    const vvl::ImageView* attachment_view = nullptr;
    if (clear_attachment.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
        if (clear_attachment.colorAttachment < info.colorAttachmentCount) {
            attachment_view = attachments[clear_attachment.colorAttachment].view.get();
        }
    } else if (clear_attachment.aspectMask & kDepthStencilAspects) {
        if (attachments.size() > info.colorAttachmentCount) {
            // If both depth and stencil attachments are defined they must both point to the same view
            attachment_view = attachments.back().view.get();
        }
    }
    return attachment_view;
}

DynamicRenderingInfo::Attachment::Attachment(const SyncValidator& state, const vku::safe_VkRenderingAttachmentInfo& attachment_info,
                                             AttachmentType type_, const VkOffset3D& offset, const VkExtent3D& extent)
    : info(attachment_info), view(state.Get<vvl::ImageView>(attachment_info.imageView)), view_gen(), type(type_) {
    if (view) {
        if (type == AttachmentType::kColor) {
            view_gen = MakeImageRangeGen(*view, offset, extent);
        } else if (type == AttachmentType::kDepth) {
            view_gen = MakeImageRangeGen(*view, offset, extent, VK_IMAGE_ASPECT_DEPTH_BIT);
        } else {
            view_gen = MakeImageRangeGen(*view, offset, extent, VK_IMAGE_ASPECT_STENCIL_BIT);
        }

        if (info.resolveImageView != VK_NULL_HANDLE && (info.resolveMode != VK_RESOLVE_MODE_NONE)) {
            resolve_view = state.Get<vvl::ImageView>(info.resolveImageView);
            if (resolve_view) {
                if (type == AttachmentType::kColor) {
                    resolve_gen.emplace(MakeImageRangeGen(*resolve_view, offset, extent));
                } else if (type == AttachmentType::kDepth) {
                    // Only the depth aspect
                    resolve_gen.emplace(MakeImageRangeGen(*resolve_view, offset, extent, VK_IMAGE_ASPECT_DEPTH_BIT));
                } else {
                    resolve_gen.emplace(MakeImageRangeGen(*resolve_view, offset, extent, VK_IMAGE_ASPECT_STENCIL_BIT));
                }
            }
        }
    }
}

ImageRangeGen DynamicRenderingInfo::Attachment::GetRangeGen(uint32_t view_mask) const {
    // VkRenderingAttachmentInfo::imageView is allowed to be VK_NULL_HANDLE
    if (!view) {
        return {};
    }
    // Multiview is disabled: return precomputed range gen
    if (view_mask == 0) {
        return view_gen;
    }
    // Initialize range gen based on view mask
    if (type == AttachmentType::kColor) {
        return MakeImageRangeGen(*view, view_mask);
    } else if (type == AttachmentType::kDepth) {
        return MakeImageRangeGen(*view, view_mask, VK_IMAGE_ASPECT_DEPTH_BIT);
    } else {
        return MakeImageRangeGen(*view, view_mask, VK_IMAGE_ASPECT_STENCIL_BIT);
    }
}

SyncAccessIndex DynamicRenderingInfo::Attachment::GetLoadUsage() const { return GetLoadOpUsageIndex(info.loadOp, type); }

SyncAccessIndex DynamicRenderingInfo::Attachment::GetStoreUsage() const { return GetStoreOpUsageIndex(info.storeOp, type); }

SyncOrdering DynamicRenderingInfo::Attachment::GetOrdering() const {
    return (type == AttachmentType::kColor) ? SyncOrdering::kColorAttachment : SyncOrdering::kDepthStencilAttachment;
}

Location DynamicRenderingInfo::Attachment::GetLocation(const Location& loc, uint32_t attachment_index) const {
    if (type == AttachmentType::kColor) {
        return loc.dot(vvl::Struct::VkRenderingAttachmentInfo, vvl::Field::pColorAttachments, attachment_index);
    } else if (type == AttachmentType::kDepth) {
        return loc.dot(vvl::Struct::VkRenderingAttachmentInfo, vvl::Field::pDepthAttachment);
    } else {
        assert(type == AttachmentType::kStencil);
        return loc.dot(vvl::Struct::VkRenderingAttachmentInfo, vvl::Field::pStencilAttachment);
    }
}

bool DynamicRenderingInfo::Attachment::IsWriteable(const LastBound& last_bound_state) const {
    bool writeable = IsValid();
    if (writeable) {
        //  Depth and Stencil have additional criteria
        if (type == AttachmentType::kDepth) {
            writeable =
                last_bound_state.IsDepthWriteEnable() && IsDepthAttachmentWriteable(last_bound_state, view->create_info.format);
        } else if (type == AttachmentType::kStencil) {
            writeable =
                last_bound_state.IsStencilTestEnable() && IsStencilAttachmentWriteable(last_bound_state, view->create_info.format);
        }
    }
    return writeable;
}

}  // namespace syncval
