// Copyright 2025 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/dawn/native/ResourceTable.h"

#include <utility>

#include "dawn/native/ValidationUtils_autogen.h"
#include "src/dawn/common/Enumerator.h"
#include "src/dawn/common/MatchVariant.h"
#include "src/dawn/common/Range.h"
#include "src/dawn/native/Buffer.h"
#include "src/dawn/native/Device.h"
#include "src/dawn/native/Queue.h"
#include "src/dawn/native/ResourceTableDefaultResources.h"
#include "src/dawn/native/Texture.h"
#include "src/utils/compiler.h"
#include "tint/tint.h"

namespace dawn::native {

namespace {

// Helper to retrieve a Ref<T> out of a variant. Returns an empty Ref if the variant doesn't hold
// Ref<T>, otherwise it returns the variant value.
template <typename T, typename Variant>
Ref<T> GetRef(Variant&& variant) {
    auto* p = std::get_if<Ref<T>>(&variant);
    if (!p) {
        return {};
    }
    return *p;
}

bool IsVisible(const TextureBase* texture, wgpu::ResourceTableUsage usage) {
    return !texture->IsDestroyed() && texture->HasAccess() &&
           usage == wgpu::ResourceTableUsage::ReadOnly;
}

MaybeValError ValidateBindingResource(const DeviceBase* device, const BindingResource* resource) {
    DAWN_INVALID_IF(resource->nextInChain != nullptr, "nextInChain is not null.");

    uint32_t resourceCount = uint32_t{resource->buffer != nullptr} +
                             uint32_t{resource->textureView != nullptr} +
                             uint32_t{resource->sampler != nullptr};
    DAWN_INVALID_IF(resourceCount != 1,
                    "%i resources are specified (when there must be exactly 1).", resourceCount);

    if (resource->buffer != nullptr) {
        // TODO(https://issues.chromium.org/473444515): Support buffers in FullResourceTable.
        return DAWN_VALIDATION_ERROR("Buffers are not supported.");
    } else if (TextureViewBase* view = resource->textureView) {
        // TODO(https://issues.chromium.org/473444515): Support texel buffers in FullResourceTable.
        DAWN_TRY(device->ValidateObject(view));

        Aspect aspect = view->GetAspects();
        DAWN_INVALID_IF(!HasOneBit(aspect),
                        "Multiple aspects (%s) selected in %s. Expected only 1.", aspect, view);

        // TODO(https://issues.chromium.org/473444515): Support storage textures in
        // FullResourceTable
        DAWN_INVALID_IF(
            (view->GetUsage() & kTextureViewOnlyUsages) != wgpu::TextureUsage::TextureBinding,
            "%s's usages (%s) are not exactly %s.", view, view->GetUsage() & kTextureViewOnlyUsages,
            wgpu::TextureUsage::TextureBinding);

        DAWN_INVALID_IF(view->IsYCbCr(), "%s is YCbCr.", view);
    } else if (SamplerBase* sampler = resource->sampler) {
        DAWN_TRY(device->ValidateObject(sampler));
        DAWN_INVALID_IF(sampler->IsYCbCr(), "%s is YCbCr.", sampler);
    } else {
        DAWN_UNREACHABLE();
    }

    return {};
}

MaybeValError ValidateUsageBindingResource(const DeviceBase* device,
                                           const UsageBindingResource* resource) {
    DAWN_INVALID_IF(resource->nextInChain != nullptr, "nextInChain is not null.");

    uint32_t resourceCount =
        uint32_t{resource->buffer != nullptr} + uint32_t{resource->texture != nullptr};
    DAWN_INVALID_IF(resourceCount != 1,
                    "%i resources are specified (when there must be exactly 1).", resourceCount);

    if (resource->buffer != nullptr) {
        // TODO(https://issues.chromium.org/473444515): Support buffers in FullResourceTable.
        return DAWN_VALIDATION_ERROR("Buffers are not supported.");
    } else if (TextureBase* texture = resource->texture) {
        DAWN_TRY(device->ValidateObject(texture));
    } else {
        DAWN_UNREACHABLE();
    }

    return {};
}

}  // anonymous namespace

MaybeValError ValidateResourceTableDescriptor(const DeviceBase* device,
                                              const ResourceTableDescriptor* descriptor) {
    DAWN_CHECK(descriptor);

    DAWN_INVALID_IF(!device->HasFeature(Feature::ChromiumExperimentalSamplingResourceTable),
                    "Resource table used without the %s feature enabled.",
                    wgpu::FeatureName::ChromiumExperimentalSamplingResourceTable);

    DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain is not nullptr.");

    return {};
}

MaybeValError ValidateSetResourceUsage(const DeviceBase* device,
                                       const ResourceTableBase* table,
                                       const UsageBindingResource* resource,
                                       wgpu::ResourceTableUsage usage) {
    DAWN_TRY(device->ValidateObject(table));
    DAWN_TRY(ValidateResourceTableUsage(usage));
    DAWN_TRY(ValidateUsageBindingResource(device, resource));

    return {};
}

ResourceTableBase::ResourceTableBase(DeviceBase* device, const ResourceTableDescriptor* descriptor)
    : ApiObjectBase(device, descriptor->label), mAPISize(ResourceTableSlot(descriptor->size)) {
    mSlots.resize(mAPISize + ResourceTableDefaultResources::GetCount());
    // This checks that the default SlotState constructor used in the resize operation will
    // initialize with the typeId of an empty slot.
    DAWN_ASSERT(ComputeTypeId({}) == SlotState{}.typeId);

    GetObjectTrackingList()->Track(this);
}

ResourceTableBase::ResourceTableBase(DeviceBase* device,
                                     const ResourceTableDescriptor* descriptor,
                                     ObjectBase::ErrorTag tag)
    : ApiObjectBase(device, tag, descriptor->label) {
    // Create the vector of SlotState even for an error resource table because we need to do state
    // tracking used for the validation of synchronous errors. However skip creating it for tables
    // above the limit because that's a special error case caught on the content-timeline as well.
    if (descriptor->size <= kMaxResourceTableSize) {
        mAPISize = ResourceTableSlot(descriptor->size);
        mSlots.resize(mAPISize);
    } else {
        mDestroyed = true;
    }
}

// static
Ref<ResourceTableBase> ResourceTableBase::MakeError(DeviceBase* device,
                                                    const ResourceTableDescriptor* descriptor) {
    return AcquireRef(new ResourceTableBase(device, descriptor, ObjectBase::kError));
}

ObjectType ResourceTableBase::GetType() const {
    return ObjectType::ResourceTable;
}

ResourceTableSlot ResourceTableBase::GetAPISize() const {
    return mAPISize;
}

ResourceTableSlot ResourceTableBase::GetSizeWithDefaultResources() const {
    return mSlots.size();
}

BufferBase* ResourceTableBase::GetMetadataBuffer() const {
    DAWN_CHECK(!mDestroyed);
    return mMetadataBuffer.Get();
}

bool ResourceTableBase::IsDestroyed() const {
    return mDestroyed;
}

MaybeValError ResourceTableBase::ValidateCanUseInSubmitNow() const {
    DAWN_CHECK(!IsError());
    DAWN_INVALID_IF(IsDestroyed(), "%s used while destroyed.", this);
    return {};
}

MaybeError ResourceTableBase::InitializeBase() {
    DeviceBase* device = GetDevice();

    // Create a storage buffer that will hold the shader-visible metadata for the dynamic array.
    uint32_t metadataArrayLength = uint32_t{GetSizeWithDefaultResources()};
    BufferDescriptor metadataDesc{
        .label = "resource table metadata",
        .usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst,
        .size = sizeof(uint32_t) * (metadataArrayLength + 1),
        .mappedAtCreation = true,
    };
    DAWN_TRY_ASSIGN(mMetadataBuffer, device->CreateBuffer(&metadataDesc));

    // Initialize the metadata buffer with the arrayLength and a bunch of zeroes that correspond to
    // empty entries.
    static_assert(tint::ResourceType{} == tint::ResourceType::kEmpty);
    // TODO(https://crbug.com/435317394): We could rely on zero initialization if it is enabled, and
    // also apply the initial dirty slots in this mapping instead of on the first use of the
    // resource table.
    Span<uint32_t> data = mMetadataBuffer->GetMappedRangeSpan<uint32_t>();
    // Store APISize at element 0 in the metadata buffer, which will be used in the shader to index
    // default resources at APISize + resource type index.
    data[0] = uint32_t{mAPISize};
    std::ranges::fill(data.subspan(1), 0u);
    DAWN_TRY(mMetadataBuffer->Unmap());

    // Add the default resources at the end of the table.
    ResourceTableDefaultResources* defaultResources;
    DAWN_TRY_ASSIGN(defaultResources, device->GetOrCreateResourceTableDefaultsResource());

    for (auto [i, defaultResource] : Enumerate(defaultResources->GetResources())) {
        BindingResource entryContents;
        MatchVariant(
            defaultResource,
            [&](Ref<TextureViewBase> view) { entryContents.textureView = view.Get(); },
            [&](Ref<SamplerBase> sampler) { entryContents.sampler = sampler.Get(); });
        Update(mAPISize + i, &entryContents);
    }

    return {};
}

void ResourceTableBase::DestroyImpl(DestroyReason reason) {
    DAWN_CHECK(!mDestroyed);

    for (const auto& [texture, _] : mTextureState) {
        texture->RemoveResourceTableUse(this);
    }

    mSlots.clear();
    mDirtySlots.clear();
    mTextureState.clear();
    mDirtyStateTextures.clear();

    if (mMetadataBuffer != nullptr) {
        mMetadataBuffer->Destroy();
        mMetadataBuffer = nullptr;
    }

    mDestroyed = true;
}

void ResourceTableBase::APIDestroy() {
    // Handle error objects directly because Destroy() will skip calling DestroyImpl for them.
    if (IsError()) {
        mSlots.clear();
        mDirtySlots.clear();
        mTextureState.clear();
        mDirtyStateTextures.clear();
        mDestroyed = true;
    } else {
        Destroy();
    }
}

wgpu::Status ResourceTableBase::APIUpdate(uint32_t slotIn, const BindingResource* resource) {
    ResourceTableSlot slot = ResourceTableSlot(slotIn);
    if (!IsValidSlot(slot)) {
        return wgpu::Status::Error;
    }

    // Prevent replacing a slot that may be in use by the GPU.
    if (mSlots[slot].availableAfter > GetDevice()->GetQueue()->GetCompletedCommandSerial()) {
        return wgpu::Status::Error;
    }

    UpdateWithDeviceValidation(slot, resource, "Update");
    return wgpu::Status::Success;
}

uint32_t ResourceTableBase::APIInsert(const BindingResource* resource) {
    if (IsDestroyed()) {
        return wgpu::kInvalidBinding;
    }

    // TODO(https://crbug.com/435317394): This is O(n) in the number of slots. We could make it
    // O(logN) with a heap of the free slots that's maintained over time.
    ExecutionSerial completedSerial = GetDevice()->GetQueue()->GetCompletedCommandSerial();
    for (ResourceTableSlot slot : Range(mAPISize)) {
        if (mSlots[slot].availableAfter > completedSerial) {
            continue;
        }

        UpdateWithDeviceValidation(slot, resource, "Insert");
        return uint32_t{slot};
    }

    // No slot found, return the invalid binding.
    return wgpu::kInvalidBinding;
}

wgpu::Status ResourceTableBase::APIRemove(uint32_t slotIn) {
    ResourceTableSlot slot = ResourceTableSlot(slotIn);
    if (!IsValidSlot(slot)) {
        return wgpu::Status::Error;
    }

    // Always remove the slot, even if a validation error happens, so that we match client-side
    // validation.
    Remove(slot);

    std::ignore = GetDevice()->ConsumedError(GetDevice()->ValidateObject(this),
                                             "validating %s.Remove(%u)", this, slot);
    return wgpu::Status::Success;
}

uint32_t ResourceTableBase::APIGetSize() const {
    return uint32_t{mAPISize};
}

void ResourceTableBase::APISetResourceUsage(const UsageBindingResource* resource,
                                            wgpu::ResourceTableUsage usage) {
    if (GetDevice()->ConsumedError(ValidateSetResourceUsage(GetDevice(), this, resource, usage),
                                   "validating %s.SetResourceUsage(%p, %s)", this, resource,
                                   usage)) {
        return;
    }

    SetResourceUsage(resource, usage);
}

void ResourceTableBase::SetResourceUsage(const UsageBindingResource* resource,
                                         wgpu::ResourceTableUsage usage) {
    DAWN_CHECK(resource->buffer == nullptr);
    TextureBase* texture = resource->texture;
    DAWN_ASSERT(texture != nullptr);
    if (IsDestroyed() || texture->IsDestroyed()) {
        return;
    }

    auto iter = mTextureState.find(texture);

    // Special-case ReadOnly to not track textures that have no slots since it is the default
    // state. This avoids keeping around references to textures that may never be put in the
    // resource table.
    if (usage == wgpu::ResourceTableUsage::ReadOnly) {
        if (iter == mTextureState.end()) {
            return;
        }
        if (iter->second.slots.empty()) {
            texture->RemoveResourceTableUse(this);
            mTextureState.erase(iter);
            return;
        }
    }

    // Track textures with non-default usage even if they are not currently in the resource
    // table, so that their usage state is remembered if they are inserted later.
    if (iter == mTextureState.end()) {
        iter = mTextureState.emplace(texture, TextureState{}).first;
        texture->AddResourceTableUse(this);
    }

    TextureState& textureState = iter->second;
    if (textureState.usage != usage) {
        textureState.usage = usage;
        OnTextureStateChange(texture);
    }
}

// static
tint::ResourceType ResourceTableBase::ComputeTypeId(
    const std::variant<std::monostate, Ref<TextureViewBase>, Ref<SamplerBase>>& resource) {
    return MatchVariant(
        resource, [&](std::monostate) { return tint::ResourceType::kEmpty; },
        [&](const Ref<SamplerBase>& sampler) {
            if (sampler->IsComparison()) {
                return tint::ResourceType::kSampler_comparison;
            }
            if (sampler->IsFiltering()) {
                return tint::ResourceType::kSampler_filtering;
            }
            return tint::ResourceType::kSampler_non_filtering;
        },
        [&](const Ref<TextureViewBase>& view) {
            const TextureBase* texture = view->GetTexture();
            if (texture->IsMultisampledTexture()) {
                DAWN_CHECK(view->GetDimension() == wgpu::TextureViewDimension::e2D);

                switch (view->GetAspects()) {
                    case Aspect::Color:
                        switch (view->GetFormat().GetAspectInfo(Aspect::Color).baseType) {
                            case TextureComponentType::Float:
                                return tint::ResourceType::kTextureMultisampled2d_f32;
                            case TextureComponentType::Uint:
                                return tint::ResourceType::kTextureMultisampled2d_u32;
                            case TextureComponentType::Sint:
                                return tint::ResourceType::kTextureMultisampled2d_i32;
                            default:
                                DAWN_UNREACHABLE();
                        }

                    case Aspect::Depth:
                        return tint::ResourceType::kTextureDepthMultisampled2d;
                    default:
                        DAWN_UNREACHABLE();
                }
            }

            if (view->GetAspects() == Aspect::Depth) {
                DAWN_CHECK(!texture->IsMultisampledTexture());

                switch (view->GetDimension()) {
                    case wgpu::TextureViewDimension::e2D:
                        return tint::ResourceType::kTextureDepth2d;
                    case wgpu::TextureViewDimension::e2DArray:
                        return tint::ResourceType::kTextureDepth2dArray;
                    case wgpu::TextureViewDimension::Cube:
                        return tint::ResourceType::kTextureDepthCube;
                    case wgpu::TextureViewDimension::CubeArray:
                        return tint::ResourceType::kTextureDepthCubeArray;
                    default:
                        DAWN_UNREACHABLE();
                }
            }

            const auto& aspect_info = view->GetFormat().GetAspectInfo(view->GetAspects());
            bool filterable = (aspect_info.supportedSampleTypes & SampleTypeBit::Float);
            switch (aspect_info.baseType) {
                case TextureComponentType::Float:
                    switch (view->GetDimension()) {
                        case wgpu::TextureViewDimension::e1D: {
                            if (filterable) {
                                return tint::ResourceType::kTexture1d_f32_filterable;
                            }
                            return tint::ResourceType::kTexture1d_f32_unfilterable;
                        }
                        case wgpu::TextureViewDimension::e2D: {
                            if (filterable) {
                                return tint::ResourceType::kTexture2d_f32_filterable;
                            }
                            return tint::ResourceType::kTexture2d_f32_unfilterable;
                        }
                        case wgpu::TextureViewDimension::e2DArray: {
                            if (filterable) {
                                return tint::ResourceType::kTexture2dArray_f32_filterable;
                            }
                            return tint::ResourceType::kTexture2dArray_f32_unfilterable;
                        }
                        case wgpu::TextureViewDimension::Cube: {
                            if (filterable) {
                                return tint::ResourceType::kTextureCube_f32_filterable;
                            }
                            return tint::ResourceType::kTextureCube_f32_unfilterable;
                        }
                        case wgpu::TextureViewDimension::CubeArray: {
                            if (filterable) {
                                return tint::ResourceType::kTextureCubeArray_f32_filterable;
                            }
                            return tint::ResourceType::kTextureCubeArray_f32_unfilterable;
                        }
                        case wgpu::TextureViewDimension::e3D: {
                            if (filterable) {
                                return tint::ResourceType::kTexture3d_f32_filterable;
                            }
                            return tint::ResourceType::kTexture3d_f32_unfilterable;
                        }
                        default:
                            DAWN_UNREACHABLE();
                    }
                case TextureComponentType::Uint:
                    switch (view->GetDimension()) {
                        case wgpu::TextureViewDimension::e1D:
                            return tint::ResourceType::kTexture1d_u32;
                        case wgpu::TextureViewDimension::e2D:
                            return tint::ResourceType::kTexture2d_u32;
                        case wgpu::TextureViewDimension::e2DArray:
                            return tint::ResourceType::kTexture2dArray_u32;
                        case wgpu::TextureViewDimension::Cube:
                            return tint::ResourceType::kTextureCube_u32;
                        case wgpu::TextureViewDimension::CubeArray:
                            return tint::ResourceType::kTextureCubeArray_u32;
                        case wgpu::TextureViewDimension::e3D:
                            return tint::ResourceType::kTexture3d_u32;
                        default:
                            DAWN_UNREACHABLE();
                    }
                case TextureComponentType::Sint:
                    switch (view->GetDimension()) {
                        case wgpu::TextureViewDimension::e1D:
                            return tint::ResourceType::kTexture1d_i32;
                        case wgpu::TextureViewDimension::e2D:
                            return tint::ResourceType::kTexture2d_i32;
                        case wgpu::TextureViewDimension::e2DArray:
                            return tint::ResourceType::kTexture2dArray_i32;
                        case wgpu::TextureViewDimension::Cube:
                            return tint::ResourceType::kTextureCube_i32;
                        case wgpu::TextureViewDimension::CubeArray:
                            return tint::ResourceType::kTextureCubeArray_i32;
                        case wgpu::TextureViewDimension::e3D:
                            return tint::ResourceType::kTexture3d_i32;
                        default:
                            DAWN_UNREACHABLE();
                    }
                default:
                    DAWN_UNREACHABLE();
            }
        });

    DAWN_UNREACHABLE();
}

bool ResourceTableBase::IsValidSlot(ResourceTableSlot slot) const {
    // Some validation is required to return a synchronous error. It needs to be able to run even on
    // error ResourceTables because it must act the same way as an implementation running on top of
    // the wire client-side and doesn't know if objects are errors or not.
    return !mDestroyed && slot < mAPISize;
}

void ResourceTableBase::Update(ResourceTableSlot slot, const BindingResource* contents) {
    DAWN_ASSERT(mSlots[slot].availableAfter <=
                GetDevice()->GetQueue()->GetCompletedCommandSerial());
    DAWN_CHECK(mSlots[slot].typeId == tint::ResourceType::kEmpty);
    mSlots[slot].availableAfter = kMaxExecutionSerial;
    SetEntry(slot, contents);
}

void ResourceTableBase::Remove(ResourceTableSlot slot) {
    // Prevent all accesses to the slot which means it will be possible to update it once all
    // current GPU work is finished.
    mSlots[slot].availableAfter = GetDevice()->GetQueue()->GetLastSubmittedCommandSerial();

    // Set the entry to be empty, which will unlink previously set resources.
    BindingResource nothing = {};
    SetEntry(slot, &nothing);
}

void ResourceTableBase::UpdateWithDeviceValidation(ResourceTableSlot slot,
                                                   const BindingResource* resource,
                                                   std::string_view methodName) {
    // Perform validation that produces a validation error, but unconditionally mark the slot as
    // used since we need to match client-side validation that doesn't perform these checks.
    if (GetDevice()->ConsumedError(  //
            ([&]() -> MaybeValError {
                DAWN_TRY(GetDevice()->ValidateObject(this));
                return ValidateBindingResource(GetDevice(), resource);
            })(),
            "validating %s.%s()", this, methodName)) {
        BindingResource nothing = {};
        Update(slot, &nothing);
    } else {
        Update(slot, resource);
    }
}

void ResourceTableBase::SetEntry(ResourceTableSlot slot, const BindingResource* contents) {
    DAWN_CHECK(contents->buffer == nullptr);
    SlotState& state = mSlots[slot];

    // Check the current state. If it's already set to the input value, early out.
    if (auto currView = GetRef<TextureViewBase>(state.resource)) {
        if (currView == contents->textureView) {
            return;
        }

        if (currView != nullptr) {
            // Remove from mTextureState
            TextureBase* currTexture = currView->GetTexture();
            TextureState& textureState = mTextureState[currTexture];
            [[maybe_unused]] const bool erased = textureState.slots.erase(slot);
            DAWN_ASSERT(erased);
            // If it's the last slot, stop tracking dirty state for this texture, and remove it
            // from mTextureState if it has default usage (ReadOnly). Otherwise, keep the
            // mTextureState entry so its non-default usage is remembered if it is added back to
            // the table.
            if (textureState.slots.empty()) {
                if (textureState.usage == wgpu::ResourceTableUsage::ReadOnly) {
                    currTexture->RemoveResourceTableUse(this);
                    mTextureState.erase(currTexture);
                }
                mDirtyStateTextures.erase(currTexture);
            }
        }
    } else if (auto sampler = GetRef<SamplerBase>(state.resource)) {
        if (sampler == contents->sampler) {
            return;
        }
    }

    // Update to new state
    state.resource = {};
    // Note: state.lastResource is only updated by AcquireDirtySlotUpdates

    if (TextureViewBase* inputView = contents->textureView) {
        TextureBase* inputTexture = inputView->GetTexture();
        // Add to mTextureState
        auto [iter, added] = mTextureState.try_emplace(inputTexture);
        TextureState& textureState = iter->second;
        if (added) {
            // Add the mapping to this table on the texture
            inputTexture->AddResourceTableUse(this);
        }
        // If inputTexture is being (re-)added to its first slot, mark it dirty so its visibility
        // and transition are evaluated before the next use. Note that we check `slots.empty()`
        // rather than `added` because an entry may already exist with non-default usage.
        if (textureState.slots.empty()) {
            mDirtyStateTextures.insert(inputTexture);
        }
        [[maybe_unused]] const bool inserted = textureState.slots.insert(slot).second;
        DAWN_ASSERT(inserted);

        state.resource = inputView;
    } else if (SamplerBase* sampler = contents->sampler) {
        state.resource = sampler;
    }

    state.typeId = ComputeTypeId(state.resource);
    state.resourceDirty = true;
    MarkStateDirty(slot);
}

MaybeError ResourceTableBase::ApplyDirtySlotUpdatesWith(
    const absl::flat_hash_set<TextureBase*>& writableTextures,
    absl::FunctionRef<ApplyUpdateFn> ApplyUpdate) {
    Updates updates = AcquireDirtySlotUpdates(writableTextures);

    DAWN_TRY(
        ApplyUpdate(updates.metadataUpdates, updates.resourceDiffs, updates.texturesToTransition));

    // The handling of updates.texturesToTransition may cause memory barriers that mark them
    // dirty again, when they have just been put in the correct state. Ignore this fake dirtying
    // by clearing mDirtyStateTextures.
#if defined(DAWN_ENABLE_ASSERTS)
    for (const auto& texture : mDirtyStateTextures) {
        DAWN_ASSERT(updates.texturesToTransition.contains(texture));
    }
#endif
    mDirtyStateTextures = std::move(updates.texturesDirtyAfterUpdate);
    return {};
}

ResourceTableBase::Updates ResourceTableBase::MakeResourcesVisibleExcept(
    const absl::flat_hash_set<TextureBase*>& writableTextures) {
    // This function uses mDirtyStateTextures and writableTextures to figure out visibility for each
    // texture in the table, returning the set of textures to transition and updating
    // mTextureState's visibility flag (marking slots dirty whenever visibility changes).
    Updates updates;

    auto HandleDirtyTexture = [&](TextureBase* texture) {
        // A texture is removed from mDirtyStateTextures whenever it is removed from mTextureState
        // (e.g. when its last slot is removed or when it is destroyed).
        auto iter = mTextureState.find(texture);
        DAWN_ASSERT(iter != mTextureState.end());
        auto& textureState = iter->second;
        // A texture is only added to mDirtyStateTextures when it has at least one slot, and removed
        // from it when it has no more slots.
        DAWN_ASSERT(!textureState.slots.empty());

        // Update visible flag
        bool visible =
            IsVisible(texture, textureState.usage) && !writableTextures.contains(texture);

        if (visible) {
            updates.texturesToTransition.insert(texture);
        }

        if (textureState.visible != visible) {
            textureState.visible = visible;

            // Mark all slots containing this texture dirty so their metadata is updated
            for (auto slot : textureState.slots) {
                MarkStateDirty(slot);
            }
        }
    };

    // First handle the textures that have been dirtied since last draw/dispatch
    for (TextureBase* texture : mDirtyStateTextures) {
        HandleDirtyTexture(texture);
    }
    // Now that we've handled them, clear
    mDirtyStateTextures.clear();

    // Now process writable textures, hiding any that are in the table.
    // We also make sure to add them to texturesDirtyAfterUpdate so that if they're not writable
    // next call, we unhide them.
    for (TextureBase* texture : writableTextures) {
        auto iter = mTextureState.find(texture);
        if (iter != mTextureState.end() && !iter->second.slots.empty()) {
            // We may be recomputing visibility unnecessarily, but it will be possible to optimize.
            HandleDirtyTexture(texture);
            updates.texturesDirtyAfterUpdate.insert(texture);
        }
    }

    return updates;
}

ResourceTableBase::Updates ResourceTableBase::AcquireDirtySlotUpdates(
    const absl::flat_hash_set<TextureBase*>& writableTextures) {
    DAWN_CHECK(!mDestroyed);

    Updates updates = MakeResourcesVisibleExcept(writableTextures);

    for (ResourceTableSlot dirtySlot : mDirtySlots) {
        SlotState& state = mSlots[dirtySlot];
        DAWN_CHECK(state.metadataDirty);
        state.metadataDirty = false;

        // Set the value in the table to the type id if visible, otherwise mark empty.
        tint::ResourceType effectiveType = state.typeId;
        if (auto view = GetRef<TextureViewBase>(state.resource)) {
            auto iter = mTextureState.find(view->GetTexture());
            DAWN_ASSERT(iter != mTextureState.end());
            effectiveType = iter->second.visible ? state.typeId : tint::ResourceType::kEmpty;
        }

        // Add the update for the metadata buffer.
        // Add 1 because the 0th element holds the table size (APISize).
        uint32_t offset = sizeof(uint32_t) * (uint32_t{dirtySlot} + 1);
        updates.metadataUpdates.push_back({
            .slot = dirtySlot,
            .offset = offset,
            .data = to_underlying(effectiveType),
        });

        // Compute whether a resource update is needed and skip adding it if unnecessary.
        if (!state.resourceDirty) {
            continue;
        }
        state.resourceDirty = false;

        ResourceDiff update{
            .slot = dirtySlot,
            .removed = state.lastResource,
            .added = state.resource,
        };

        // At least one of removed and added must be set
        DAWN_ASSERT(!(std::holds_alternative<std::monostate>(update.removed) &&
                      std::holds_alternative<std::monostate>(update.added)));

        updates.resourceDiffs.push_back(update);

        // Update the last resource for future slot updates
        state.lastResource = state.resource;
    }

    mDirtySlots.clear();
    return updates;
}

void ResourceTableBase::MarkStateDirty(ResourceTableSlot slot) {
    if (!mSlots[slot].metadataDirty) {
        mDirtySlots.push_back(slot);
        mSlots[slot].metadataDirty = true;
    }
}

void ResourceTableBase::OnTextureStateChange(TextureBase* texture) {
    auto iter = mTextureState.find(texture);
    DAWN_ASSERT(iter != mTextureState.end());
    if (!iter->second.slots.empty()) {
        mDirtyStateTextures.insert(texture);
    }
}

void ResourceTableBase::OnTextureDestroyed(TextureBase* texture) {
    auto iter = mTextureState.find(texture);
    DAWN_ASSERT(iter != mTextureState.end());
    // Make sure all slots for this texture are hidden
    for (auto slot : iter->second.slots) {
        SlotState& state = mSlots[slot];
        state.resource = std::monostate{};
        state.typeId = tint::ResourceType::kEmpty;
        state.resourceDirty = true;
        MarkStateDirty(slot);
    }
    mTextureState.erase(iter);
    mDirtyStateTextures.erase(texture);
}

}  // namespace dawn::native
