diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 2263084552..fd6d569aa9 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -49,6 +49,7 @@ list(APPEND UNITTEST_SOURCES ${VALIDATION_TESTS_DIR}/InputStateValidationTests.cpp ${VALIDATION_TESTS_DIR}/PushConstantsValidationTests.cpp ${VALIDATION_TESTS_DIR}/RenderPassValidationTests.cpp + ${VALIDATION_TESTS_DIR}/RenderPipelineValidationTests.cpp ${VALIDATION_TESTS_DIR}/UsageValidationTests.cpp ${VALIDATION_TESTS_DIR}/ValidationTest.cpp ${VALIDATION_TESTS_DIR}/ValidationTest.h diff --git a/src/tests/unittests/validation/RenderPipelineValidationTests.cpp b/src/tests/unittests/validation/RenderPipelineValidationTests.cpp new file mode 100644 index 0000000000..1923c9ed11 --- /dev/null +++ b/src/tests/unittests/validation/RenderPipelineValidationTests.cpp @@ -0,0 +1,161 @@ +// Copyright 2017 The NXT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "tests/unittests/validation/ValidationTest.h" + +#include "utils/NXTHelpers.h" + +class RenderPipelineValidationTest : public ValidationTest { + protected: + void SetUp() override { + ValidationTest::SetUp(); + + utils::CreateDefaultRenderPass(device, &renderpass, &framebuffer); + + pipelineLayout = device.CreatePipelineLayoutBuilder().GetResult(); + + inputState = device.CreateInputStateBuilder().GetResult(); + + vsModule = utils::CreateShaderModule(device, nxt::ShaderStage::Vertex, R"( + #version 450 + void main() { + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + })" + ); + + fsModule = utils::CreateShaderModule(device, nxt::ShaderStage::Fragment, R"( + #version 450 + out vec4 fragColor; + void main() { + fragColor = vec4(0.0, 1.0, 0.0, 1.0); + })" + ); + } + + nxt::RenderPipelineBuilder& AddDefaultStates(nxt::RenderPipelineBuilder&& builder) { + builder.SetSubpass(renderpass, 0) + .SetLayout(pipelineLayout) + .SetStage(nxt::ShaderStage::Vertex, vsModule, "main") + .SetStage(nxt::ShaderStage::Fragment, fsModule, "main") + .SetPrimitiveTopology(nxt::PrimitiveTopology::Triangle); + return builder; + } + + nxt::RenderPass renderpass; + nxt::Framebuffer framebuffer; + nxt::ShaderModule vsModule; + nxt::ShaderModule fsModule; + nxt::InputState inputState; + nxt::PipelineLayout pipelineLayout; +}; + +// Test cases where creation should succeed +TEST_F(RenderPipelineValidationTest, CreationSuccess) { + AddDefaultStates(AssertWillBeSuccess(device.CreateRenderPipelineBuilder())) + .GetResult(); +} + +// Test creation failure when properties are missing +TEST_F(RenderPipelineValidationTest, CreationMissingProperty) { + // Vertex stage not set + { + AssertWillBeError(device.CreateRenderPipelineBuilder()) + .SetSubpass(renderpass, 0) + .SetLayout(pipelineLayout) + .SetStage(nxt::ShaderStage::Fragment, fsModule, "main") + .SetPrimitiveTopology(nxt::PrimitiveTopology::Triangle) + .GetResult(); + } + + // Fragment stage not set + { + AssertWillBeError(device.CreateRenderPipelineBuilder()) + .SetSubpass(renderpass, 0) + .SetLayout(pipelineLayout) + .SetStage(nxt::ShaderStage::Vertex, vsModule, "main") + .SetPrimitiveTopology(nxt::PrimitiveTopology::Triangle) + .GetResult(); + } + + // Subpass not set + { + AssertWillBeError(device.CreateRenderPipelineBuilder()) + .SetLayout(pipelineLayout) + .SetStage(nxt::ShaderStage::Vertex, vsModule, "main") + .SetStage(nxt::ShaderStage::Fragment, fsModule, "main") + .SetPrimitiveTopology(nxt::PrimitiveTopology::Triangle) + .GetResult(); + } +} + +// TODO(enga@google.com): These should be added to the test above when validation is implemented +TEST_F(RenderPipelineValidationTest, DISABLED_TodoCreationMissingProperty) { + // Fails because pipeline layout is not set + { + AssertWillBeError(device.CreateRenderPipelineBuilder()) + .SetSubpass(renderpass, 0) + .SetStage(nxt::ShaderStage::Vertex, vsModule, "main") + .SetStage(nxt::ShaderStage::Fragment, fsModule, "main") + .SetPrimitiveTopology(nxt::PrimitiveTopology::Triangle) + .GetResult(); + } + + // Fails because primitive topology is not set + { + AssertWillBeError(device.CreateRenderPipelineBuilder()) + .SetSubpass(renderpass, 0) + .SetLayout(pipelineLayout) + .SetStage(nxt::ShaderStage::Vertex, vsModule, "main") + .SetStage(nxt::ShaderStage::Fragment, fsModule, "main") + .GetResult(); + } +} + +// Test creation failure when specifying properties multiple times +TEST_F(RenderPipelineValidationTest, DISABLED_CreationDuplicates) { + // Fails because input state is set twice + { + AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder())) + .SetInputState(inputState) + .GetResult(); + } + + // Fails because primitive topology is set twice + { + AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder())) + .SetPrimitiveTopology(nxt::PrimitiveTopology::Triangle) + .GetResult(); + } + + // Fails because vertex stage is set twice + { + AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder())) + .SetStage(nxt::ShaderStage::Fragment, fsModule, "main") + .GetResult(); + } + + // Fails because fragment stage is set twice + { + AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder())) + .SetStage(nxt::ShaderStage::Vertex, vsModule, "main") + .GetResult(); + } + + // Fails because subpass is set twice + { + AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder())) + .SetSubpass(renderpass, 0) + .GetResult(); + } +}