chromium/third_party/dawn/src/dawn/tests/unittests/SubresourceStorageTests.cpp

// 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 <algorithm>
#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 {

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 {};

// 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>
void FakeStorage<T>::CheckSameAs(const SubresourceStorage<T>& real) {}

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

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

struct SmallData {};

bool operator==(const SmallData& a, const SmallData& b) {}

// Tests that the MaybeError version of Iterate returns the first error that it encounters.
TEST(SubresourceStorageTest, IterateMaybeError) {}

// Test that the default value is correctly set.
TEST(SubresourceStorageTest, DefaultValue) {}

// 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) {}

// Test updating a single subresource on a single-aspect storage.
TEST(SubresourceStorageTest, SingleSubresourceUpdateSingleAspect) {}

// Test updating a single subresource on a multi-aspect storage.
TEST(SubresourceStorageTest, SingleSubresourceUpdateMultiAspect) {}

// Test updating as a stipple pattern on one of two aspects then updating it completely.
TEST(SubresourceStorageTest, UpdateStipple) {}

// 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) {}

// Test updating with extremal subresources
//    - Then half of the array layers in full.
//    - Then updating completely.
TEST(SubresourceStorageTest, UpdateExtremas) {}

// 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) {}

// 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) {}

// Test merging two fully compressed single-aspect resources.
TEST(SubresourceStorageTest, MergeFullWithFullSingleAspect) {}

// Test merging two fully compressed multi-aspect resources.
TEST(SubresourceStorageTest, MergeFullWithFullMultiAspect) {}

// 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) {}
// 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) {}

// 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) {}

// Regression test for a missing check that layer 0 is compressed when recompressing.
TEST(SubresourceStorageTest, Layer0NotCompressedBlocksAspectRecompression) {}

// Regression test for aspect decompression not copying to layer 0
TEST(SubresourceStorageTest, AspectDecompressionUpdatesLayer0) {}

// Check that fill after creation overwrites whatever was passed as initial value.
TEST(SubresourceStorageTest, FillAfterInitialization) {}

// Check that fill after some modification overwrites everything and recompresses.
TEST(SubresourceStorageTest, FillAfterModificationRecompresses) {}

// 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