chromium/third_party/dawn/src/dawn/tests/end2end/TextureZeroInitTests.cpp

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

#include "dawn/common/Math.h"
#include "dawn/tests/DawnTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/TestUtils.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

#define EXPECT_LAZY_CLEAR(N, statement)

class TextureZeroInitTest : public DawnTest {};

// This tests that the code path of CopyTextureToBuffer clears correctly to Zero after first usage
TEST_P(TextureZeroInitTest, CopyTextureToBufferSource) {}

// This tests that the code path of CopyTextureToBuffer with multiple texture array layers clears
// correctly to Zero after first usage
TEST_P(TextureZeroInitTest, CopyMultipleTextureArrayLayersToBufferSource) {}

// Test that non-zero mip level clears subresource to Zero after first use
// This goes through the BeginRenderPass's code path
TEST_P(TextureZeroInitTest, RenderingMipMapClearsToZero) {}

// Test that non-zero array layers clears subresource to Zero after first use.
// This goes through the BeginRenderPass's code path
TEST_P(TextureZeroInitTest, RenderingArrayLayerClearsToZero) {}

// This tests CopyBufferToTexture fully overwrites copy so lazy init is not needed.
TEST_P(TextureZeroInitTest, CopyBufferToTexture) {}

// Test for a copy only to a subset of the subresource, lazy init is necessary to clear the other
// half.
TEST_P(TextureZeroInitTest, CopyBufferToTextureHalf) {}

// This tests CopyBufferToTexture fully overwrites a range of subresources, so lazy initialization
// is needed for neither the subresources involved in the copy nor the other subresources.
TEST_P(TextureZeroInitTest, CopyBufferToTextureMultipleArrayLayers) {}

// This tests CopyTextureToTexture fully overwrites copy so lazy init is not needed.
TEST_P(TextureZeroInitTest, CopyTextureToTexture) {}

// This Tests the CopyTextureToTexture's copy only to a subset of the subresource, lazy init is
// necessary to clear the other half.
TEST_P(TextureZeroInitTest, CopyTextureToTextureHalf) {}

// This tests the texture with depth attachment and load op load will init depth stencil texture to
// 0s.
TEST_P(TextureZeroInitTest, RenderingLoadingDepth) {}

// This tests the texture with stencil attachment and load op load will init depth stencil texture
// to 0s.
TEST_P(TextureZeroInitTest, RenderingLoadingStencil) {}

// This tests the texture with depth stencil attachment and load op load will init depth stencil
// texture to 0s.
TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencil) {}

// Test that clear state is tracked independently for depth/stencil textures.
TEST_P(TextureZeroInitTest, IndependentDepthStencilLoadAfterDiscard) {}

// Test that a stencil texture that is written via copy, then discarded, sees
// zero contents when it is read by sampling.
TEST_P(TextureZeroInitTest, StencilCopyThenDiscardAndReadBySampling) {}

// Test that a stencil texture that is written via copy, then discarded, sees
// zero contents when it is read via copy.
TEST_P(TextureZeroInitTest, StencilCopyThenDiscardAndReadByCopy) {}

// Test that a stencil texture that is written via copy, then discarded, then copied to
// another texture, sees zero contents when it is read via copy.
TEST_P(TextureZeroInitTest, StencilCopyThenDiscardAndCopyToTextureThenReadByCopy) {}

// Test that clear state is tracked independently for depth/stencil textures.
// Lazy clear of the stencil aspect via copy should not touch depth.
TEST_P(TextureZeroInitTest, IndependentDepthStencilCopyAfterDiscard) {}

// This tests the color attachments clear to 0s
TEST_P(TextureZeroInitTest, ColorAttachmentsClear) {}

// This tests the clearing of sampled textures in render pass
TEST_P(TextureZeroInitTest, RenderPassSampledTextureClear) {}

// This is a regression test for a bug where a texture wouldn't get clear for a pass if at least
// one of its subresources was used as an attachment. It tests that if a texture is used as both
// sampled and attachment (with LoadOp::Clear so the lazy clear can be skipped) then the sampled
// subresource is correctly cleared.
TEST_P(TextureZeroInitTest, TextureBothSampledAndAttachmentClear) {}

// This tests the clearing of sampled textures during compute pass
TEST_P(TextureZeroInitTest, ComputePassSampledTextureClear) {}

// This tests that the code path of CopyTextureToBuffer clears correctly for non-renderable textures
TEST_P(TextureZeroInitTest, NonRenderableTextureClear) {}

// This tests that the code path of CopyTextureToBuffer clears correctly for non-renderable textures
TEST_P(TextureZeroInitTest, NonRenderableTextureClearUnalignedSize) {}

// This tests that the code path of CopyTextureToBuffer clears correctly for non-renderable textures
// with more than 1 array layers
TEST_P(TextureZeroInitTest, NonRenderableTextureClearWithMultiArrayLayers) {}

// This tests that storeOp clear resets resource state to uninitialized.
// Start with a sample texture that is initialized with data.
// Then expect the render texture to not store the data from sample texture
// because it will be lazy cleared by the EXPECT_TEXTURE_EQ call.
TEST_P(TextureZeroInitTest, RenderPassStoreOpClear) {}

// This tests storeOp Clear on depth and stencil textures.
// We put the depth stencil texture through 2 passes:
// 1) LoadOp::Clear and StoreOp::Discard, fail the depth and stencil test set in the render
//      pipeline. This means nothing is drawn and subresource is set as uninitialized.
// 2) LoadOp::Load and StoreOp::Discard, pass the depth and stencil test set in the render pipeline.
//      Because LoadOp is Load and the subresource is uninitialized, the texture will be cleared to
//      0's This means the depth and stencil test will pass and the red square is drawn.
TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencilStoreOpClear) {}

// Test that if one mip of a texture is initialized and another is uninitialized, lazy clearing the
// uninitialized mip does not clear the initialized mip.
TEST_P(TextureZeroInitTest, PreservesInitializedMip) {}

// Test that if one layer of a texture is initialized and another is uninitialized, lazy clearing
// the uninitialized layer does not clear the initialized layer.
TEST_P(TextureZeroInitTest, PreservesInitializedArrayLayer) {}

// This is a regression test for crbug.com/dawn/451 where the lazy texture
// init path on D3D12 had a divide-by-zero exception in the copy split logic.
TEST_P(TextureZeroInitTest, CopyTextureToBufferNonRenderableUnaligned) {}

// In this test WriteTexture fully overwrites a texture
TEST_P(TextureZeroInitTest, WriteWholeTexture) {}

// Test WriteTexture to a subset of the texture, lazy init is necessary to clear the other
// half.
TEST_P(TextureZeroInitTest, WriteTextureHalf) {}

// In this test WriteTexture fully overwrites a range of subresources, so lazy initialization
// is needed for neither the subresources involved in the write nor the other subresources.
TEST_P(TextureZeroInitTest, WriteWholeTextureArray) {}

// Test WriteTexture to a subset of the subresource, lazy init is necessary to clear the other
// half.
TEST_P(TextureZeroInitTest, WriteTextureArrayHalf) {}

// In this test WriteTexture fully overwrites a texture at mip level.
TEST_P(TextureZeroInitTest, WriteWholeTextureAtMipLevel) {}

// Test WriteTexture to a subset of the texture at mip level, lazy init is necessary to clear the
// other half.
TEST_P(TextureZeroInitTest, WriteTextureHalfAtMipLevel) {}

// Test that error textures are always considered uninitialized.
TEST_P(TextureZeroInitTest, ErrorTextureIsUninitialized) {}

DAWN_INSTANTIATE_TEST(
    TextureZeroInitTest,
    D3D11Backend({};

class CompressedTextureZeroInitTest : public TextureZeroInitTest {};

//  Test that the clearing is skipped when we use a full mip copy (with the physical size different
//  than the virtual mip size)
TEST_P(CompressedTextureZeroInitTest, FullMipCopy) {}

// Test that 1 lazy clear count happens when we copy to half the texture
TEST_P(CompressedTextureZeroInitTest, HalfCopyBufferToTexture) {}

// Test that 0 lazy clear count happens when we copy buffer to texture to a nonzero mip level
// (with physical size different from the virtual mip size)
TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroMipLevel) {}

// Test that 1 lazy clear count happens when we copy buffer to half texture to a nonzero mip level
// (with physical size different from the virtual mip size)
TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroMipLevel) {}

// Test that 0 lazy clear count happens when we copy buffer to nonzero array layer
TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroArrayLayer) {}

// Test that 1 lazy clear count happens when we copy buffer to half texture to a nonzero array layer
TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroArrayLayer) {}

// full copy texture to texture, 0 lazy clears are needed
TEST_P(CompressedTextureZeroInitTest, FullCopyTextureToTextureMipLevel) {}

// half copy texture to texture, lazy clears are needed for noncopied half
TEST_P(CompressedTextureZeroInitTest, HalfCopyTextureToTextureMipLevel) {}

// Test uploading then reading back from a 2D array compressed texture.
// This is a regression test for a bug where the final destination buffer
// was considered fully initialized even though there was a 256-byte
// stride between images.
TEST_P(CompressedTextureZeroInitTest, Copy2DArrayCompressedB2T2B) {}

DAWN_INSTANTIATE_TEST(CompressedTextureZeroInitTest,
                      D3D11Backend({};

}  // anonymous namespace
}  // namespace dawn