// Copyright 2020 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 <memory>
#include <string>
#include <vector>

#include "dawn/common/Log.h"
#include "dawn/native/SubresourceStorage.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace dawn::native {

using ::testing::HasSubstr;

// A fake class that replicates the behavior of SubresourceStorage but without any compression
// and is used to compare the results of operations on SubresourceStorage against the "ground
// truth" of FakeStorage.
template <typename T>
struct FakeStorage {
    FakeStorage(Aspect aspects,
                uint32_t arrayLayerCount,
                uint32_t mipLevelCount,
                T initialValue = {})
        : mAspects(aspects),
          mArrayLayerCount(arrayLayerCount),
          mMipLevelCount(mipLevelCount),
          mData(GetAspectCount(aspects) * arrayLayerCount * mipLevelCount, initialValue) {}

    template <typename F>
    void Update(const SubresourceRange& range, F&& updateFunc) {
        for (Aspect aspect : IterateEnumMask(range.aspects)) {
            for (uint32_t layer = range.baseArrayLayer;
                 layer < range.baseArrayLayer + range.layerCount; layer++) {
                for (uint32_t level = range.baseMipLevel;
                     level < range.baseMipLevel + range.levelCount; level++) {
                    SubresourceRange updateRange =
                        SubresourceRange::MakeSingle(aspect, layer, level);
                    updateFunc(updateRange, &mData[GetDataIndex(aspect, layer, level)]);
                }
            }
        }
    }

    template <typename U, typename F>
    void Merge(const SubresourceStorage<U>& other, F&& mergeFunc) {
        for (Aspect aspect : IterateEnumMask(mAspects)) {
            for (uint32_t layer = 0; layer < mArrayLayerCount; layer++) {
                for (uint32_t level = 0; level < mMipLevelCount; level++) {
                    SubresourceRange range = SubresourceRange::MakeSingle(aspect, layer, level);
                    mergeFunc(range, &mData[GetDataIndex(aspect, layer, level)],
                              other.Get(aspect, layer, level));
                }
            }
        }
    }

    const T& Get(Aspect aspect, uint32_t arrayLayer, uint32_t mipLevel) const {
        return mData[GetDataIndex(aspect, arrayLayer, mipLevel)];
    }

    size_t GetDataIndex(Aspect aspect, uint32_t layer, uint32_t level) const {
        uint32_t aspectIndex = GetAspectIndex(aspect);
        return level + mMipLevelCount * (layer + mArrayLayerCount * aspectIndex);
    }

    // Method that checks that this and real have exactly the same content. It does so via
    // looping on all subresources and calling Get() (hence testing Get()). It also calls
    // Iterate() checking that every subresource is mentioned exactly once and that its content
    // is correct (hence testing Iterate()). Its implementation requires the RangeTracker below
    // that itself needs FakeStorage<int> so it cannot be define inline with the other methods.
    void CheckSameAs(const SubresourceStorage<T>& real);

    Aspect mAspects;
    uint32_t mArrayLayerCount;
    uint32_t mMipLevelCount;

    std::vector<T> mData;
};

// Track a set of ranges that have been seen and can assert that in aggregate they make exactly
// a single range (and that each subresource was seen only once).
struct RangeTracker {
    template <typename T>
    explicit RangeTracker(const SubresourceStorage<T>& s)
        : mTracked(s.GetAspectsForTesting(),
                   s.GetArrayLayerCountForTesting(),
                   s.GetMipLevelCountForTesting(),
                   0) {}

    void Track(const SubresourceRange& range) {
        // Add +1 to the subresources tracked.
        mTracked.Update(range, [](const SubresourceRange&, uint32_t* counter) {
            ASSERT_EQ(*counter, 0u);
            *counter += 1;
        });
    }

    void CheckTrackedExactly(const SubresourceRange& range) {
        // Check that all subresources in the range were tracked once and set the counter back
        // to 0.
        mTracked.Update(range, [](const SubresourceRange&, uint32_t* counter) {
            ASSERT_EQ(*counter, 1u);
            *counter = 0;
        });

        // Now all subresources should be at 0.
        for (int counter : mTracked.mData) {
            ASSERT_EQ(counter, 0);
        }
    }

    FakeStorage<uint32_t> mTracked;
};

template <typename T>
void FakeStorage<T>::CheckSameAs(const SubresourceStorage<T>& real) {
    EXPECT_EQ(real.GetAspectsForTesting(), mAspects);
    EXPECT_EQ(real.GetArrayLayerCountForTesting(), mArrayLayerCount);
    EXPECT_EQ(real.GetMipLevelCountForTesting(), mMipLevelCount);

    RangeTracker tracker(real);
    real.Iterate([&](const SubresourceRange& range, const T& data) {
        // Check that the range is sensical.
        EXPECT_TRUE(IsSubset(range.aspects, mAspects));

        EXPECT_LT(range.baseArrayLayer, mArrayLayerCount);
        EXPECT_LE(range.baseArrayLayer + range.layerCount, mArrayLayerCount);

        EXPECT_LT(range.baseMipLevel, mMipLevelCount);
        EXPECT_LE(range.baseMipLevel + range.levelCount, mMipLevelCount);

        for (Aspect aspect : IterateEnumMask(range.aspects)) {
            for (uint32_t layer = range.baseArrayLayer;
                 layer < range.baseArrayLayer + range.layerCount; layer++) {
                for (uint32_t level = range.baseMipLevel;
                     level < range.baseMipLevel + range.levelCount; level++) {
                    EXPECT_EQ(data, Get(aspect, layer, level));
                    EXPECT_EQ(data, real.Get(aspect, layer, level));
                }
            }
        }

        tracker.Track(range);
    });

    tracker.CheckTrackedExactly(
        SubresourceRange::MakeFull(mAspects, mArrayLayerCount, mMipLevelCount));
}

template <typename T>
void CheckAspectCompressed(const SubresourceStorage<T>& s, Aspect aspect, bool expected) {
    DAWN_ASSERT(HasOneBit(aspect));

    uint32_t levelCount = s.GetMipLevelCountForTesting();
    uint32_t layerCount = s.GetArrayLayerCountForTesting();

    bool seen = false;
    s.Iterate([&](const SubresourceRange& range, const T&) {
        if (range.aspects == aspect && range.layerCount == layerCount &&
            range.levelCount == levelCount && range.baseArrayLayer == 0 &&
            range.baseMipLevel == 0) {
            seen = true;
        }
    });

    ASSERT_EQ(seen, expected);

    // Check that the internal state of SubresourceStorage matches what we expect.
    // If an aspect is compressed, all its layers should be internally tagged as compressed.
    ASSERT_EQ(s.IsAspectCompressedForTesting(aspect), expected);
    if (expected) {
        for (uint32_t layer = 0; layer < s.GetArrayLayerCountForTesting(); layer++) {
            ASSERT_TRUE(s.IsLayerCompressedForTesting(aspect, layer));
        }
    }
}

template <typename T>
void CheckLayerCompressed(const SubresourceStorage<T>& s,
                          Aspect aspect,
                          uint32_t layer,
                          bool expected) {
    DAWN_ASSERT(HasOneBit(aspect));

    uint32_t levelCount = s.GetMipLevelCountForTesting();

    bool seen = false;
    s.Iterate([&](const SubresourceRange& range, const T&) {
        if (range.aspects == aspect && range.layerCount == 1 && range.levelCount == levelCount &&
            range.baseArrayLayer == layer && range.baseMipLevel == 0) {
            seen = true;
        }
    });

    ASSERT_EQ(seen, expected);
    ASSERT_EQ(s.IsLayerCompressedForTesting(aspect, layer), expected);
}

struct SmallData {
    uint32_t value = 0xF00;
};

bool operator==(const SmallData& a, const SmallData& b) {
    return a.value == b.value;
}

// Tests that the MaybeError version of Iterate returns the first error that it encounters.
TEST(SubresourceStorageTest, IterateMaybeError) {
    // Create a resource with multiple layers of different data so that we can ensure that the
    // iterate function runs more than once.
    constexpr uint32_t kLayers = 4;
    SubresourceStorage<uint32_t> s(Aspect::Color, kLayers, 1);
    for (uint32_t layer = 0; layer < kLayers; layer++) {
        s.Update(SubresourceRange::MakeSingle(Aspect::Color, layer, 0),
                 [&](const SubresourceRange&, uint32_t* data) { *data = layer + 1; });
    }

    // Make sure that the first error is returned.
    uint32_t errorLayer = 0;
    MaybeError maybeError =
        s.Iterate([&](const SubresourceRange& range, const uint32_t& layer) -> MaybeError {
            if (!errorLayer) {
                errorLayer = layer;
            }
            return DAWN_VALIDATION_ERROR("Errored at layer: %d", layer);
        });
    ASSERT_TRUE(maybeError.IsError());
    std::unique_ptr<ErrorData> error = maybeError.AcquireError();
    EXPECT_THAT(error->GetFormattedMessage(), HasSubstr(std::to_string(errorLayer)));
}

// Test that the default value is correctly set.
TEST(SubresourceStorageTest, DefaultValue) {
    // Test setting no default value for a primitive type.
    {
        SubresourceStorage<int> s(Aspect::Color, 3, 5);
        EXPECT_EQ(s.Get(Aspect::Color, 1, 2), 0);

        FakeStorage<int> f(Aspect::Color, 3, 5);
        f.CheckSameAs(s);
    }

    // Test setting a default value for a primitive type.
    {
        SubresourceStorage<int> s(Aspect::Color, 3, 5, 42);
        EXPECT_EQ(s.Get(Aspect::Color, 1, 2), 42);

        FakeStorage<int> f(Aspect::Color, 3, 5, 42);
        f.CheckSameAs(s);
    }

    // Test setting no default value for a type with a default constructor.
    {
        SubresourceStorage<SmallData> s(Aspect::Color, 3, 5);
        EXPECT_EQ(s.Get(Aspect::Color, 1, 2).value, 0xF00u);

        FakeStorage<SmallData> f(Aspect::Color, 3, 5);
        f.CheckSameAs(s);
    }
    // Test setting a default value for a type with a default constructor.
    {
        SubresourceStorage<SmallData> s(Aspect::Color, 3, 5, {007u});
        EXPECT_EQ(s.Get(Aspect::Color, 1, 2).value, 007u);

        FakeStorage<SmallData> f(Aspect::Color, 3, 5, {007u});
        f.CheckSameAs(s);
    }
}

// The tests for Update() all follow the same pattern of setting up a real and a fake storage
// then performing one or multiple Update()s on them and checking:
//  - They have the same content.
//  - The Update() range was correct.
//  - The aspects and layers have the expected "compressed" status.

// Calls Update both on the read storage and the fake storage but intercepts the call to
// updateFunc done by the real storage to check their ranges argument aggregate to exactly the
// update range.
template <typename T, typename F>
void CallUpdateOnBoth(SubresourceStorage<T>* s,
                      FakeStorage<T>* f,
                      const SubresourceRange& range,
                      F&& updateFunc) {
    RangeTracker tracker(*s);

    s->Update(range, [&](const SubresourceRange& range, T* data) {
        tracker.Track(range);
        updateFunc(range, data);
    });
    f->Update(range, updateFunc);

    tracker.CheckTrackedExactly(range);
    f->CheckSameAs(*s);
}

// Test updating a single subresource on a single-aspect storage.
TEST(SubresourceStorageTest, SingleSubresourceUpdateSingleAspect) {
    SubresourceStorage<int> s(Aspect::Color, 5, 7);
    FakeStorage<int> f(Aspect::Color, 5, 7);

    // Update a single subresource.
    SubresourceRange range = SubresourceRange::MakeSingle(Aspect::Color, 3, 2);
    CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data += 1; });

    CheckAspectCompressed(s, Aspect::Color, false);
    CheckLayerCompressed(s, Aspect::Color, 2, true);
    CheckLayerCompressed(s, Aspect::Color, 3, false);
    CheckLayerCompressed(s, Aspect::Color, 4, true);
}

// Test updating a single subresource on a multi-aspect storage.
TEST(SubresourceStorageTest, SingleSubresourceUpdateMultiAspect) {
    SubresourceStorage<int> s(Aspect::Depth | Aspect::Stencil, 5, 3);
    FakeStorage<int> f(Aspect::Depth | Aspect::Stencil, 5, 3);

    SubresourceRange range = SubresourceRange::MakeSingle(Aspect::Stencil, 1, 2);
    CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data += 1; });

    CheckAspectCompressed(s, Aspect::Depth, true);
    CheckAspectCompressed(s, Aspect::Stencil, false);
    CheckLayerCompressed(s, Aspect::Stencil, 0, true);
    CheckLayerCompressed(s, Aspect::Stencil, 1, false);
    CheckLayerCompressed(s, Aspect::Stencil, 2, true);
}

// Test updating as a stipple pattern on one of two aspects then updating it completely.
TEST(SubresourceStorageTest, UpdateStipple) {
    const uint32_t kLayers = 10;
    const uint32_t kLevels = 7;
    SubresourceStorage<int> s(Aspect::Depth | Aspect::Stencil, kLayers, kLevels);
    FakeStorage<int> f(Aspect::Depth | Aspect::Stencil, kLayers, kLevels);

    // Update with a stipple.
    for (uint32_t layer = 0; layer < kLayers; layer++) {
        for (uint32_t level = 0; level < kLevels; level++) {
            if ((layer + level) % 2 == 0) {
                SubresourceRange range = SubresourceRange::MakeSingle(Aspect::Depth, layer, level);
                CallUpdateOnBoth(&s, &f, range,
                                 [](const SubresourceRange&, int* data) { *data += 17; });
            }
        }
    }

    // The depth should be fully uncompressed while the stencil stayed compressed.
    CheckAspectCompressed(s, Aspect::Stencil, true);
    CheckAspectCompressed(s, Aspect::Depth, false);
    for (uint32_t layer = 0; layer < kLayers; layer++) {
        CheckLayerCompressed(s, Aspect::Depth, layer, false);
    }

    // Update completely with a single value. Recompression should happen!
    {
        SubresourceRange fullRange =
            SubresourceRange::MakeFull(Aspect::Depth | Aspect::Stencil, kLayers, kLevels);
        CallUpdateOnBoth(&s, &f, fullRange, [](const SubresourceRange&, int* data) { *data = 31; });
    }

    CheckAspectCompressed(s, Aspect::Depth, true);
    CheckAspectCompressed(s, Aspect::Stencil, true);
}

// Test updating as a crossing band pattern:
//  - The first band is full layers [2, 3] on both aspects
//  - The second band is full mips [5, 6] on one aspect.
// Then updating completely.
TEST(SubresourceStorageTest, UpdateTwoBand) {
    const uint32_t kLayers = 5;
    const uint32_t kLevels = 9;
    SubresourceStorage<int> s(Aspect::Depth | Aspect::Stencil, kLayers, kLevels);
    FakeStorage<int> f(Aspect::Depth | Aspect::Stencil, kLayers, kLevels);

    // Update the two bands
    {
        SubresourceRange range(Aspect::Depth | Aspect::Stencil, {2, 2}, {0, kLevels});
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data += 3; });
    }

    // The layers were fully updated so they should stay compressed.
    CheckLayerCompressed(s, Aspect::Depth, 2, true);
    CheckLayerCompressed(s, Aspect::Depth, 3, true);
    CheckLayerCompressed(s, Aspect::Stencil, 2, true);
    CheckLayerCompressed(s, Aspect::Stencil, 3, true);

    {
        SubresourceRange range(Aspect::Depth, {0, kLayers}, {5, 2});
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data *= 3; });
    }

    // The layers had to be decompressed in depth
    CheckLayerCompressed(s, Aspect::Depth, 2, false);
    CheckLayerCompressed(s, Aspect::Depth, 3, false);
    CheckLayerCompressed(s, Aspect::Stencil, 2, true);
    CheckLayerCompressed(s, Aspect::Stencil, 3, true);

    // Update completely. Without a single value recompression shouldn't happen.
    {
        SubresourceRange fullRange =
            SubresourceRange::MakeFull(Aspect::Depth | Aspect::Stencil, kLayers, kLevels);
        CallUpdateOnBoth(&s, &f, fullRange,
                         [](const SubresourceRange&, int* data) { *data += 12; });
    }

    CheckAspectCompressed(s, Aspect::Depth, false);
    CheckAspectCompressed(s, Aspect::Stencil, false);
}

// Test updating with extremal subresources
//    - Then half of the array layers in full.
//    - Then updating completely.
TEST(SubresourceStorageTest, UpdateExtremas) {
    const uint32_t kLayers = 6;
    const uint32_t kLevels = 4;
    SubresourceStorage<int> s(Aspect::Color, kLayers, kLevels);
    FakeStorage<int> f(Aspect::Color, kLayers, kLevels);

    // Update the two extrema
    {
        SubresourceRange range = SubresourceRange::MakeSingle(Aspect::Color, 0, kLevels - 1);
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data += 3; });
    }
    {
        SubresourceRange range = SubresourceRange::MakeSingle(Aspect::Color, kLayers - 1, 0);
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data *= 3; });
    }

    CheckLayerCompressed(s, Aspect::Color, 0, false);
    CheckLayerCompressed(s, Aspect::Color, 1, true);
    CheckLayerCompressed(s, Aspect::Color, kLayers - 2, true);
    CheckLayerCompressed(s, Aspect::Color, kLayers - 1, false);

    // Update half of the layers in full with constant values. Some recompression should happen.
    {
        SubresourceRange range(Aspect::Color, {0, kLayers / 2}, {0, kLevels});
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data = 123; });
    }

    CheckLayerCompressed(s, Aspect::Color, 0, true);
    CheckLayerCompressed(s, Aspect::Color, 1, true);
    CheckLayerCompressed(s, Aspect::Color, kLayers - 1, false);

    // Update completely. Recompression should happen!
    {
        SubresourceRange fullRange = SubresourceRange::MakeFull(Aspect::Color, kLayers, kLevels);
        CallUpdateOnBoth(&s, &f, fullRange, [](const SubresourceRange&, int* data) { *data = 35; });
    }

    CheckAspectCompressed(s, Aspect::Color, true);
}

// A regression test for an issue found while reworking the implementation where
// RecompressAspect didn't correctly check that each each layer was compressed but only that
// their 0th value was the same.
TEST(SubresourceStorageTest, UpdateLevel0sHappenToMatch) {
    SubresourceStorage<int> s(Aspect::Color, 2, 2);
    FakeStorage<int> f(Aspect::Color, 2, 2);

    // Update 0th mip levels to some value, it should decompress the aspect and both layers.
    {
        SubresourceRange range(Aspect::Color, {0, 2}, {0, 1});
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data = 17; });
    }

    CheckAspectCompressed(s, Aspect::Color, false);
    CheckLayerCompressed(s, Aspect::Color, 0, false);
    CheckLayerCompressed(s, Aspect::Color, 1, false);

    // Update the whole resource by doing +1. The aspects and layers should stay decompressed.
    {
        SubresourceRange range = SubresourceRange::MakeFull(Aspect::Color, 2, 2);
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data += 1; });
    }

    CheckAspectCompressed(s, Aspect::Color, false);
    CheckLayerCompressed(s, Aspect::Color, 0, false);
    CheckLayerCompressed(s, Aspect::Color, 1, false);
}

// The tests for Merge() all follow the same as the Update() tests except that they use Update()
// to set up the test storages.

// Similar to CallUpdateOnBoth but for Merge
template <typename T, typename U, typename F>
void CallMergeOnBoth(SubresourceStorage<T>* s,
                     FakeStorage<T>* f,
                     const SubresourceStorage<U>& other,
                     F&& mergeFunc) {
    RangeTracker tracker(*s);

    s->Merge(other, [&](const SubresourceRange& range, T* data, const U& otherData) {
        tracker.Track(range);
        mergeFunc(range, data, otherData);
    });
    f->Merge(other, mergeFunc);

    tracker.CheckTrackedExactly(
        SubresourceRange::MakeFull(f->mAspects, f->mArrayLayerCount, f->mMipLevelCount));
    f->CheckSameAs(*s);
}

// Test merging two fully compressed single-aspect resources.
TEST(SubresourceStorageTest, MergeFullWithFullSingleAspect) {
    SubresourceStorage<int> s(Aspect::Color, 4, 6);
    FakeStorage<int> f(Aspect::Color, 4, 6);

    // Merge the whole resource in a single call.
    SubresourceStorage<bool> other(Aspect::Color, 4, 6, true);
    CallMergeOnBoth(&s, &f, other, [](const SubresourceRange&, int* data, bool other) {
        if (other) {
            *data = 13;
        }
    });

    CheckAspectCompressed(s, Aspect::Color, true);
}

// Test merging two fully compressed multi-aspect resources.
TEST(SubresourceStorageTest, MergeFullWithFullMultiAspect) {
    SubresourceStorage<int> s(Aspect::Depth | Aspect::Stencil, 6, 7);
    FakeStorage<int> f(Aspect::Depth | Aspect::Stencil, 6, 7);

    // Merge the whole resource in a single call.
    SubresourceStorage<bool> other(Aspect::Depth | Aspect::Stencil, 6, 7, true);
    CallMergeOnBoth(&s, &f, other, [](const SubresourceRange&, int* data, bool other) {
        if (other) {
            *data = 13;
        }
    });

    CheckAspectCompressed(s, Aspect::Depth, true);
    CheckAspectCompressed(s, Aspect::Stencil, true);
}

// Test merging a fully compressed resource in a resource with the "cross band" pattern.
//  - The first band is full layers [2, 3] on both aspects
//  - The second band is full mips [5, 6] on one aspect.
// This provides coverage of using a single piece of data from `other` to update all of `s`
TEST(SubresourceStorageTest, MergeFullInTwoBand) {
    const uint32_t kLayers = 5;
    const uint32_t kLevels = 9;
    SubresourceStorage<int> s(Aspect::Depth | Aspect::Stencil, kLayers, kLevels);
    FakeStorage<int> f(Aspect::Depth | Aspect::Stencil, kLayers, kLevels);

    // Update the two bands
    {
        SubresourceRange range(Aspect::Depth | Aspect::Stencil, {2, 2}, {0, kLevels});
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data += 3; });
    }
    {
        SubresourceRange range(Aspect::Depth, {0, kLayers}, {5, 2});
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data += 5; });
    }

    // Merge the fully compressed resource.
    SubresourceStorage<int> other(Aspect::Depth | Aspect::Stencil, kLayers, kLevels, 17);
    CallMergeOnBoth(&s, &f, other,
                    [](const SubresourceRange&, int* data, int other) { *data += other; });

    // The layers traversed by the mip band are still uncompressed.
    CheckLayerCompressed(s, Aspect::Depth, 1, false);
    CheckLayerCompressed(s, Aspect::Depth, 2, false);
    CheckLayerCompressed(s, Aspect::Depth, 3, false);
    CheckLayerCompressed(s, Aspect::Depth, 4, false);

    // Stencil is decompressed but all its layers are still compressed because there wasn't the
    // mip band.
    CheckAspectCompressed(s, Aspect::Stencil, false);
    CheckLayerCompressed(s, Aspect::Stencil, 1, true);
    CheckLayerCompressed(s, Aspect::Stencil, 2, true);
    CheckLayerCompressed(s, Aspect::Stencil, 3, true);
    CheckLayerCompressed(s, Aspect::Stencil, 4, true);
}
// Test the reverse, mergign two-bands in a full resource. This provides coverage for
// decompressing aspects / and partilly layers to match the compression of `other`
TEST(SubresourceStorageTest, MergeTwoBandInFull) {
    const uint32_t kLayers = 5;
    const uint32_t kLevels = 9;
    SubresourceStorage<int> s(Aspect::Depth | Aspect::Stencil, kLayers, kLevels, 75);
    FakeStorage<int> f(Aspect::Depth | Aspect::Stencil, kLayers, kLevels, 75);

    // Update the two bands
    SubresourceStorage<int> other(Aspect::Depth | Aspect::Stencil, kLayers, kLevels);
    {
        SubresourceRange range(Aspect::Depth | Aspect::Stencil, {2, 2}, {0, kLevels});
        other.Update(range, [](const SubresourceRange&, int* data) { *data += 3; });
    }
    {
        SubresourceRange range(Aspect::Depth, {0, kLayers}, {5, 2});
        other.Update(range, [](const SubresourceRange&, int* data) { *data += 5; });
    }

    // Merge the fully compressed resource.
    CallMergeOnBoth(&s, &f, other,
                    [](const SubresourceRange&, int* data, int other) { *data += other; });

    // The layers traversed by the mip band are still uncompressed.
    CheckLayerCompressed(s, Aspect::Depth, 1, false);
    CheckLayerCompressed(s, Aspect::Depth, 2, false);
    CheckLayerCompressed(s, Aspect::Depth, 3, false);
    CheckLayerCompressed(s, Aspect::Depth, 4, false);

    // Stencil is decompressed but all its layers are still compressed because there wasn't the
    // mip band.
    CheckAspectCompressed(s, Aspect::Stencil, false);
    CheckLayerCompressed(s, Aspect::Stencil, 1, true);
    CheckLayerCompressed(s, Aspect::Stencil, 2, true);
    CheckLayerCompressed(s, Aspect::Stencil, 3, true);
    CheckLayerCompressed(s, Aspect::Stencil, 4, true);
}

// Test merging storage with a layer band in a stipple patterned storage. This provide coverage
// for the code path that uses the same layer data for other multiple times.
TEST(SubresourceStorageTest, MergeLayerBandInStipple) {
    const uint32_t kLayers = 3;
    const uint32_t kLevels = 5;

    SubresourceStorage<int> s(Aspect::Color, kLayers, kLevels);
    FakeStorage<int> f(Aspect::Color, kLayers, kLevels);
    SubresourceStorage<int> other(Aspect::Color, kLayers, kLevels);

    for (uint32_t layer = 0; layer < kLayers; layer++) {
        for (uint32_t level = 0; level < kLevels; level++) {
            if ((layer + level) % 2 == 0) {
                SubresourceRange range = SubresourceRange::MakeSingle(Aspect::Color, layer, level);
                CallUpdateOnBoth(&s, &f, range,
                                 [](const SubresourceRange&, int* data) { *data += 17; });
            }
        }
        if (layer % 2 == 0) {
            other.Update({Aspect::Color, {layer, 1}, {0, kLevels}},
                         [](const SubresourceRange&, int* data) { *data += 8; });
        }
    }

    // Merge the band in the stipple.
    CallMergeOnBoth(&s, &f, other,
                    [](const SubresourceRange&, int* data, int other) { *data += other; });

    // None of the resulting layers are compressed.
    CheckLayerCompressed(s, Aspect::Color, 0, false);
    CheckLayerCompressed(s, Aspect::Color, 1, false);
    CheckLayerCompressed(s, Aspect::Color, 2, false);
}

// Regression test for a missing check that layer 0 is compressed when recompressing.
TEST(SubresourceStorageTest, Layer0NotCompressedBlocksAspectRecompression) {
    const uint32_t kLayers = 2;
    const uint32_t kLevels = 2;
    SubresourceStorage<int> s(Aspect::Color, kLayers, kLevels);
    FakeStorage<int> f(Aspect::Color, kLayers, kLevels);

    // Set up s with zeros except (0, 1) which is garbage.
    {
        SubresourceRange range = SubresourceRange::MakeSingle(Aspect::Color, 0, 1);
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data += 0xABC; });
    }

    // Other is 2x2 of zeroes
    SubresourceStorage<int> other(Aspect::Color, kLayers, kLevels);

    // Fake updating F with other which is fully compressed and will trigger recompression.
    CallMergeOnBoth(&s, &f, other, [](const SubresourceRange&, int*, int) {});

    // The Color aspect should not have been recompressed.
    CheckAspectCompressed(s, Aspect::Color, false);
    CheckLayerCompressed(s, Aspect::Color, 0, false);
}

// Regression test for aspect decompression not copying to layer 0
TEST(SubresourceStorageTest, AspectDecompressionUpdatesLayer0) {
    const uint32_t kLayers = 2;
    const uint32_t kLevels = 2;
    SubresourceStorage<int> s(Aspect::Color, kLayers, kLevels, 3);
    FakeStorage<int> f(Aspect::Color, kLayers, kLevels, 3);

    // Cause decompression by writing to a single subresource.
    {
        SubresourceRange range = SubresourceRange::MakeSingle(Aspect::Color, 1, 1);
        CallUpdateOnBoth(&s, &f, range, [](const SubresourceRange&, int* data) { *data += 0xABC; });
    }

    // Check that the aspect's value of 3 was correctly decompressed in layer 0.
    CheckLayerCompressed(s, Aspect::Color, 0, true);
    EXPECT_EQ(3, s.Get(Aspect::Color, 0, 0));
    EXPECT_EQ(3, s.Get(Aspect::Color, 0, 1));
}

// Bugs found while testing:
//  - mLayersCompressed not initialized to true.
//  - DecompressLayer setting Compressed to true instead of false.
//  - Get() checking for !compressed instead of compressed for the early exit.
//  - DAWN_ASSERT in RecompressLayers was inverted.
//  - Two != being converted to == during a rework.
//  - (with DAWN_ASSERT) that RecompressAspect didn't check that aspect 0 was compressed.
//  - Missing decompression of layer 0 after introducing mInlineAspectData.

}  // namespace dawn::native
