blob: 2366d77740096b5cc9e29897d6a4711507f6b478 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ui/lib/escher/test/common/gtest_escher.h"
#include "src/ui/lib/escher/third_party/granite/vk/shader_utils.h"
namespace {
using namespace escher;
using namespace impl;
using PushConstantRangeTest = test::TestWithVkValidationLayer;
// Test a single push constant range. It should come back as is.
VK_TEST_F(PushConstantRangeTest, SingleRange) {
vk::PushConstantRange range({}, 0, 50);
std::vector<vk::PushConstantRange> array = {range};
auto result = ConsolidatePushConstantRanges(array);
EXPECT_EQ(result[0], range);
}
// Check two push constant ranges with no overlap. The result should
// be the same exact two ranges that were input.
VK_TEST_F(PushConstantRangeTest, NoOverlap) {
vk::PushConstantRange range1(vk::ShaderStageFlagBits::eVertex, 0, 50);
vk::PushConstantRange range2(vk::ShaderStageFlagBits::eFragment, 60, 100);
std::vector<vk::PushConstantRange> array = {range1, range2};
auto result = ConsolidatePushConstantRanges(array);
EXPECT_EQ(result.size(), 2U);
EXPECT_EQ(result[0], range1);
EXPECT_EQ(result[1], range2) << result[1].offset << " " << result[1].size << " "
<< to_string(result[1].stageFlags);
}
// Check two push constant ranges that do overlap. The result should
// be a single push constant range with 2 shader stages.
//
// First range goes from [0,50] and the second range goes from [40, 140]
// so the final output should have range [0, 140].
VK_TEST_F(PushConstantRangeTest, TwoOverlapping) {
vk::PushConstantRange range1(vk::ShaderStageFlagBits::eVertex, 0, 50);
vk::PushConstantRange range2(vk::ShaderStageFlagBits::eFragment, 40, 100);
std::vector<vk::PushConstantRange> array = {range1, range2};
auto result = ConsolidatePushConstantRanges(array);
EXPECT_EQ(result.size(), 1U);
EXPECT_EQ(result[0].offset, 0U);
EXPECT_EQ(result[0].size, 140U);
EXPECT_EQ(result[0].stageFlags,
vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment);
}
// This unit test contains a range that completely encapsulates another range.
// The end result should be a single range with two shader stages whose offset
// and size match the outer range.
VK_TEST_F(PushConstantRangeTest, WhollyContainedRange) {
vk::PushConstantRange range1(vk::ShaderStageFlagBits::eVertex, 0, 100);
vk::PushConstantRange range2(vk::ShaderStageFlagBits::eFragment, 40, 50);
std::vector<vk::PushConstantRange> array = {range1, range2};
auto result = ConsolidatePushConstantRanges(array);
EXPECT_EQ(result.size(), 1U);
EXPECT_EQ(result[0].offset, 0U);
EXPECT_EQ(result[0].size, 100U);
EXPECT_EQ(result[0].stageFlags,
vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment);
}
// Two ranges that are adjacent, meaning that range1 ends exactly where range2
// begins should be considered two different ranges. For example if range one
// goes from (0,60) and range two goes from (60, 100), those are two ranges.
VK_TEST_F(PushConstantRangeTest, AdjacentRanges) {
vk::PushConstantRange range1(vk::ShaderStageFlagBits::eVertex, 0, 60);
vk::PushConstantRange range2(vk::ShaderStageFlagBits::eFragment, 60, 50);
std::vector<vk::PushConstantRange> array = {range1, range2};
auto result = ConsolidatePushConstantRanges(array);
EXPECT_EQ(result.size(), 2U);
EXPECT_EQ(result[0].offset, 0U);
EXPECT_EQ(result[0].size, 60U);
EXPECT_EQ(result[1].offset, 60U);
EXPECT_EQ(result[1].size, 50U);
}
// Check multiple ranges that span vertex, fragment and compute shaders.
// Order is given randomly in order to test that sorting works as well.
VK_TEST_F(PushConstantRangeTest, MultipleRanges) {
vk::PushConstantRange range1(vk::ShaderStageFlagBits::eFragment, 40, 40);
vk::PushConstantRange range2(vk::ShaderStageFlagBits::eVertex, 0, 50);
vk::PushConstantRange range3(vk::ShaderStageFlagBits::eCompute, 80, 40);
vk::PushConstantRange range4(vk::ShaderStageFlagBits::eFragment, 100, 10);
vk::PushConstantRange range5(vk::ShaderStageFlagBits::eCompute, 90, 10);
std::vector<vk::PushConstantRange> array = {range1, range2, range3, range4, range5};
auto result = ConsolidatePushConstantRanges(array);
EXPECT_EQ(result.size(), 2U);
EXPECT_EQ(result[0].offset, 0U);
EXPECT_EQ(result[0].size, 80U);
EXPECT_EQ(result[0].stageFlags,
vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment);
EXPECT_EQ(result[1].offset, 80U);
EXPECT_EQ(result[1].size, 40U);
EXPECT_EQ(result[1].stageFlags,
vk::ShaderStageFlagBits::eCompute | vk::ShaderStageFlagBits::eFragment);
}
} // anonymous namespace