chromium/third_party/dawn/src/dawn/tests/unittests/validation/RenderPipelineValidationTests.cpp

// Copyright 2017 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 <cmath>
#include <sstream>
#include <string>
#include <vector>

#include "dawn/common/Constants.h"
#include "dawn/tests/unittests/validation/ValidationTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

class RenderPipelineValidationTest : public ValidationTest {};

bool BlendFactorContainsSrcAlpha(const wgpu::BlendFactor& blendFactor) {}

// Test cases where creation should succeed
TEST_F(RenderPipelineValidationTest, CreationSuccess) {}

// Tests that depth bias parameters must not be NaN.
TEST_F(RenderPipelineValidationTest, DepthBiasParameterNotBeNaN) {}

/// Tests that depthBias can't be used with point or line topologies.
TEST_F(RenderPipelineValidationTest, DepthBiasNotWithPointLine) {}

// Tests that depth or stencil aspect is required if we enable depth or stencil test.
TEST_F(RenderPipelineValidationTest, DepthStencilAspectRequirement) {}

// Tests that depth attachment is required when frag_depth is written in fragment stage.
TEST_F(RenderPipelineValidationTest, DepthAttachmentRequiredWhenFragDepthIsWritten) {}

// Tests that at least one color target state is required.
TEST_F(RenderPipelineValidationTest, ColorTargetStateRequired) {}

// Tests that target blend must not be set if the format is undefined.
TEST_F(RenderPipelineValidationTest, UndefinedColorStateFormatWithBlend) {}

// Tests that a color target that's present in the pipeline descriptor but not in the shader must
// have its writeMask set to 0.
TEST_F(RenderPipelineValidationTest, WriteMaskMustBeZeroForColorTargetWithNoShaderOutput) {}

// Tests that the color formats must be renderable.
TEST_F(RenderPipelineValidationTest, NonRenderableFormat) {}

// Tests that the color formats must be blendable when blending is enabled.
// Those are renderable color formats with "float" capabilities in
// https://gpuweb.github.io/gpuweb/#plain-color-formats
TEST_F(RenderPipelineValidationTest, NonBlendableFormat) {}

// Tests that the format of the color state descriptor must match the output of the fragment shader.
TEST_F(RenderPipelineValidationTest, FragmentOutputFormatCompatibility) {}

// Tests that the component count of the color state target format must be fewer than that of the
// fragment shader output.
TEST_F(RenderPipelineValidationTest, FragmentOutputComponentCountCompatibility) {}

// Tests that when blendOperationMinOrMax is "min" or "max", both srcBlendFactor and dstBlendFactor
// must be "one".
TEST_F(RenderPipelineValidationTest, BlendOperationAndBlendFactors) {}

// Tests that enums enabled by the DualSourceBlending feature are not valid when the feature is not
// enabled.
TEST_F(RenderPipelineValidationTest, DualSourceBlendingEnumsInvalid) {}

/// Tests that the sample count of the render pipeline must be valid.
TEST_F(RenderPipelineValidationTest, SampleCount) {}

// Tests that the sample count of the render pipeline must be equal to the one of every attachments
// in the render pass.
TEST_F(RenderPipelineValidationTest, SampleCountCompatibilityWithRenderPass) {}

// Tests that the vertex only pipeline must be used with a depth-stencil attachment only render pass
TEST_F(RenderPipelineValidationTest, VertexOnlyPipelineRequireDepthStencilAttachment) {}

// Tests that the sample count of the render pipeline must be valid
// when the alphaToCoverage mode is enabled.
TEST_F(RenderPipelineValidationTest, AlphaToCoverageAndSampleCount) {}

// Tests if the sample_mask builtin is a pipeline output of fragment shader,
// then alphaToCoverageEnabled must be false.
TEST_F(RenderPipelineValidationTest, AlphaToCoverageAndSampleMaskOutput) {}

// Tests when alphaToCoverageEnabled is true, targets[0] must exist and have alpha channel.
TEST_F(RenderPipelineValidationTest, AlphaToCoverageAndColorTargetAlpha) {}

// Tests that the texture component type in shader must match the bind group layout.
TEST_F(RenderPipelineValidationTest, TextureComponentTypeCompatibility) {}

// Tests that the texture view dimension in shader must match the bind group layout.
TEST_F(RenderPipelineValidationTest, TextureViewDimensionCompatibility) {}

// Test that declaring a storage buffer in the vertex shader without setting pipeline layout won't
// cause crash.
TEST_F(RenderPipelineValidationTest, StorageBufferInVertexShaderNoLayout) {}

// Tests that only strip primitive topologies allow an index format
TEST_F(RenderPipelineValidationTest, StripIndexFormatAllowed) {}

// Test that setting unclippedDepth to true is an error if the feature is not enabled.
TEST_F(RenderPipelineValidationTest, UnclippedDepthWithoutFeature) {}

// Test that depthStencil.depthCompare is required only for formats with depth.
TEST_F(RenderPipelineValidationTest, DepthCompareRequiredForFormatsWithDepth) {}

// Test that depthStencil.depthWriteEnabled is required only for formats with depth.
TEST_F(RenderPipelineValidationTest, DepthWriteEnabledRequiredForFormatsWithDepth) {}

// Test that the entryPoint names must be present for the correct stage in the shader module.
TEST_F(RenderPipelineValidationTest, EntryPointNameValidation) {}

// Check that entry points are optional.
TEST_F(RenderPipelineValidationTest, EntryPointNameOptional) {}

// Check that entry points are required if module has multiple entry points.
TEST_F(RenderPipelineValidationTest, EntryPointNameRequiredIfMultipleEntryPoints) {}

// Check that entry points are required if module has no compatible entry points.
TEST_F(RenderPipelineValidationTest, EntryPointNameRequiredIfNoCompatibleEntryPoints) {}

// Test that vertex attrib validation is for the correct entryPoint
TEST_F(RenderPipelineValidationTest, VertexAttribCorrectEntryPoint) {}

// Test that fragment output validation is for the correct entryPoint
TEST_F(RenderPipelineValidationTest, FragmentOutputCorrectEntryPoint) {}

// Test that unwritten fragment outputs must have a write mask of 0.
TEST_F(RenderPipelineValidationTest, UnwrittenFragmentOutputsMask0) {}

// Test that fragment output validation is for the correct entryPoint
TEST_F(RenderPipelineValidationTest, BindingsFromCorrectEntryPoint) {}

// Tests validation for per-pixel accounting for render targets. The tests currently assume that the
// default maxColorAttachmentBytesPerSample limit of 32 is used.
TEST_F(RenderPipelineValidationTest, RenderPipelineColorAttachmentBytesPerSample) {}

// Creating render pipeline with ColorTargetStateExpandResolveTextureDawn without enabling
// LoadResolveTexture feature should result in error.
TEST_F(RenderPipelineValidationTest, LoadResolveTextureOnUnsupportedDevice) {}

/// Tests that depthBias can't be used with point or line topologies.
TEST_F(RenderPipelineValidationTest, PointLineDepthBias) {}

class DepthClipControlValidationTest : public RenderPipelineValidationTest {};

// Tests that specifying a unclippedDepth value succeeds if the feature is enabled.
TEST_F(DepthClipControlValidationTest, Success) {}

class InterStageVariableMatchingValidationTest : public RenderPipelineValidationTest {};

// Tests that creating render pipeline should fail when there is a fragment input that
// doesn't have its corresponding vertex output at the same location.
TEST_F(InterStageVariableMatchingValidationTest, MissingDeclarationAtSameLocation) {}

// Tests that creating render pipeline should fail when the type of a vertex stage output variable
// doesn't match the type of the fragment stage input variable at the same location.
TEST_F(InterStageVariableMatchingValidationTest, DifferentTypeAtSameLocation) {}

// Tests that creating render pipeline should fail when the interpolation attribute of a vertex
// stage output variable doesn't match the type of the fragment stage input variable at the same
// location.
TEST_F(InterStageVariableMatchingValidationTest, DifferentInterpolationAttributeAtSameLocation) {}

class RenderPipelineTransientAttachmentValidationTest : public RenderPipelineValidationTest {};

// Test case where creation should succeed.
TEST_F(RenderPipelineTransientAttachmentValidationTest, CreationSuccess) {}

// Creation of a pipeline that stores into a transient attachment should cause
// an error.
TEST_F(RenderPipelineTransientAttachmentValidationTest, StoreCausesError) {}

// Creation of a pipeline that loads from a transient attachment should cause
// an error.
TEST_F(RenderPipelineTransientAttachmentValidationTest, LoadCausesError) {}

class LoadResolveTexturePipelineDescriptorValidationTest : public RenderPipelineValidationTest {};

// Test that creating and using a render pipeline with ColorTargetStateExpandResolveTextureDawn
// chained struct should success.
TEST_F(LoadResolveTexturePipelineDescriptorValidationTest, ValidUse) {}

// Test that creating and using a render pipeline with ColorTargetStateExpandResolveTextureDawn
// chained struct in a non-zero indexed attachment should success.
TEST_F(LoadResolveTexturePipelineDescriptorValidationTest, UseInNonZeroIndexedAttachment) {}

// If a render pipeline's MultisampleState contains ColorTargetStateExpandResolveTextureDawn
// chained struct. Then its sampleCount must be > 1.
TEST_F(LoadResolveTexturePipelineDescriptorValidationTest,
       PipelineSampleCountMustBeGreaterThanOne) {}

// If a render pipeline is created with ColorTargetStateExpandResolveTextureDawn.enabled =
// true, then it cannot be used in a render pass that wasn't created with ExpandResolveTexture load
// op.
TEST_F(LoadResolveTexturePipelineDescriptorValidationTest,
       ExpandResolveTexturePipeline_UseIn_NormalRenderPass_Error) {}

// Using a normal render pipeline in a ExpandResolveTexture render pass should result in
// incompatible error.
TEST_F(LoadResolveTexturePipelineDescriptorValidationTest,
       NormalPipeline_Use_In_ExpandResolveTextureRenderPass_Error) {}

// Test that the following scenario works:
// - Render pipeline and render pass both have two color outputs with resolve targets.
// - Only second output uses ExpandResolveTexture.
TEST_F(LoadResolveTexturePipelineDescriptorValidationTest,
       RenderPipelineAndRenderPassTwoOuputsLoadColor1) {}

// Test that the following render pipeline and render pass are incompatible.
// - Render pass:
//   - colorAttachments[0]
//     - has resolveTarget.
//     - loadOp = ExpandResolveTexture.
//   - colorAttachments[1]
//     - has resolveTarget.
//     - loadOp = Load.
// - Render pipeline:
//   - colorTargets[0].nextInChain contains ColorTargetStateExpandResolveTextureDawn.
//     - ColorTargetStateExpandResolveTextureDawn.enabled = true.
//   - colorTargets[1].nextInChain = null.
// They are incompatible by spec's requirements.
TEST_F(LoadResolveTexturePipelineDescriptorValidationTest,
       RenderPipelineAndRenderPassMismatchResolveTargetsError) {}

// Test that the following render pipeline and render pass are incompatible.
// - Render pass:
//   - colorAttachments[0]
//     - has resolveTarget.
//     - loadOp = ExpandResolveTexture.
//   - colorAttachments[1]
//     - has **no** resolveTarget.
// - Render pipeline:
//   - colorTargets[0].nextInChain = ColorTargetStateExpandResolveTextureDawn.
//     - ColorTargetStateExpandResolveTextureDawn.enabled = true.
//   - colorTargets[1].nextInChain = ColorTargetStateExpandResolveTextureDawn.
//     - ColorTargetStateExpandResolveTextureDawn.enabled = false.
// They are incompatible by spec's requirements.
TEST_F(LoadResolveTexturePipelineDescriptorValidationTest,
       RenderPipelineAndRenderPassMismatchResolveTargetsError2) {}

// Bind resolve attachment in a ExpandResolveTexture render pass as texture should result
// in error.
TEST_F(LoadResolveTexturePipelineDescriptorValidationTest, BindColorAttachmentAsTextureError) {}

class DualSourceBlendingFeatureTest : public RenderPipelineValidationTest {};

// Tests that enums associated with the DualSourceBlending feature are valid when the feature is
// enabled.
TEST_F(DualSourceBlendingFeatureTest, FeatureEnumsValidWithFeatureEnabled) {}

// Test that rendering to multiple render targets while using dual source blending results in an
// error.
TEST_F(DualSourceBlendingFeatureTest, MultipleRenderTargetsNotAllowed) {}

// Test that when any blend factor uses `src1` `@blend_src(1)` must be declared in the fragment
// shader.
TEST_F(DualSourceBlendingFeatureTest, BlendFactorSrc1RequiresBlendSrc1InWGSL) {}

// Test that when any color blend factor uses the alpha channel of `src1` the fragment shader output
// with `@blend_src(1)` must have an alpha channel.
TEST_F(DualSourceBlendingFeatureTest, ColorBlendFactorSrc1AlphaRequiresBlendSrc1AlphaInWGSL) {}

// Test that it is valid to declare `@blend_src(1)` before `@blend_src(0)`.
TEST_F(DualSourceBlendingFeatureTest, BlendSrc1BeforeBlendSrc0) {}

// Test that it is valid to use a constant expression as `@blend_src` attribute.
TEST_F(DualSourceBlendingFeatureTest, ConstValueAsBlendSrc) {}

// Test that when `Src` is used in the blend factor, it is not allowed to have multiple color
// targets, even when all the color targets whose index is non-zero have a color mask equal to None.
TEST_F(DualSourceBlendingFeatureTest, MultipleColorTargets) {}

class FramebufferFetchFeatureTest : public RenderPipelineValidationTest {};

// Test that the framebuffer input must have a corresponding color target.
TEST_F(FramebufferFetchFeatureTest, FramebufferInputMustHaveColorTarget) {}

// Test that the framebuffer fetch type matches the texture format exactly.
TEST_F(FramebufferFetchFeatureTest, InputMatchesFormat) {}

}  // anonymous namespace
}  // namespace dawn