1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2020 Valve Corporation.
6 * Copyright (c) 2020 The Khronos Group Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Amber tests in the GLSL group.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktAmberDepthTests.hpp"
26 #include "vktAmberTestCase.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28 #include "vktTestGroupUtil.hpp"
29
30 #include "vkQueryUtil.hpp"
31
32 #include "tcuCommandLine.hpp"
33
34 #include <vector>
35 #include <utility>
36 #include <string>
37
38 namespace vkt
39 {
40 namespace cts_amber
41 {
42
43 using namespace vk;
44
45 de::SharedPtr<Move<vk::VkDevice>> g_singletonDeviceDepthGroup;
46
47 class DepthTestCase : public AmberTestCase
48 {
49 bool m_useCustomDevice;
50
51 public:
DepthTestCase(tcu::TestContext & testCtx,const char * name,const char * description,bool useCustomDevice,const std::string & readFilename)52 DepthTestCase (tcu::TestContext& testCtx,
53 const char* name,
54 const char* description,
55 bool useCustomDevice,
56 const std::string& readFilename)
57 : AmberTestCase(testCtx, name, description, readFilename),
58 m_useCustomDevice(useCustomDevice)
59 { }
60
createInstance(Context & ctx) const61 TestInstance* createInstance (Context& ctx) const
62 {
63 // Create a custom device to ensure that VK_EXT_depth_range_unrestricted is not enabled
64 if (!g_singletonDeviceDepthGroup && m_useCustomDevice)
65 {
66 const float queuePriority = 1.0f;
67
68 // Create a universal queue that supports graphics and compute
69 const VkDeviceQueueCreateInfo queueParams =
70 {
71 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
72 DE_NULL, // pNext
73 0u, // flags
74 ctx.getUniversalQueueFamilyIndex(), // queueFamilyIndex
75 1u, // queueCount
76 &queuePriority // pQueuePriorities
77 };
78
79 const char *ext = "VK_EXT_depth_clamp_zero_one";
80
81 VkPhysicalDeviceFeatures2 features2 = initVulkanStructure();
82
83 VkPhysicalDeviceDepthClampZeroOneFeaturesEXT clampParams =
84 {
85 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_EXT, // sType
86 DE_NULL, // pNext
87 VK_TRUE, // depthClampZeroOne
88 };
89
90 features2.pNext = &clampParams;
91
92 const auto& vki = ctx.getInstanceInterface();
93 const auto physicalDevice = ctx.getPhysicalDevice();
94
95 ctx.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
96 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
97
98 const VkDeviceCreateInfo deviceCreateInfo =
99 {
100 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
101 &features2, // pNext
102 (VkDeviceCreateFlags)0u, // flags
103 1, // queueRecordCount
104 &queueParams, // pRequestedQueues
105 0, // layerCount
106 DE_NULL, // ppEnabledLayerNames
107 1, // enabledExtensionCount
108 &ext, // ppEnabledExtensionNames
109 DE_NULL, // pEnabledFeatures
110 };
111
112 const bool validation = ctx.getTestContext().getCommandLine().isValidationEnabled();
113 Move<VkDevice> device = createCustomDevice(validation, ctx.getPlatformInterface(), ctx.getInstance(), vki, physicalDevice, &deviceCreateInfo);
114
115 g_singletonDeviceDepthGroup = de::SharedPtr<Move<VkDevice>>(new Move<VkDevice>(device));
116 }
117 return new AmberTestInstance(ctx, m_recipe, m_useCustomDevice ? g_singletonDeviceDepthGroup->get() : nullptr);
118 }
119 };
120
121 struct TestInfo
122 {
123 std::string name;
124 std::string desc;
125 std::vector<std::string> base_required_features;
126 bool unrestricted;
127 };
128
createDepthTestCase(tcu::TestContext & testCtx,const TestInfo & testInfo,const char * category,const std::string & filename)129 DepthTestCase* createDepthTestCase (tcu::TestContext& testCtx,
130 const TestInfo& testInfo,
131 const char* category,
132 const std::string& filename)
133
134 {
135 // shader_test files are saved in <path>/external/vulkancts/data/vulkan/amber/<categoryname>/
136 std::string readFilename("vulkan/amber/");
137 readFilename.append(category);
138 readFilename.append("/");
139 readFilename.append(filename);
140
141 DepthTestCase *testCase = new DepthTestCase(testCtx, testInfo.name.c_str(), testInfo.desc.c_str(), !testInfo.unrestricted, readFilename);
142
143 for (auto req : testInfo.base_required_features)
144 testCase->addRequirement(req);
145
146 if (testInfo.unrestricted)
147 testCase->addRequirement("VK_EXT_depth_range_unrestricted");
148
149 return testCase;
150 }
151
createTests(tcu::TestCaseGroup * g)152 static void createTests(tcu::TestCaseGroup *g)
153 {
154 static const std::vector<TestInfo> tests =
155 {
156 { "fs_clamp", "Test fragment shader depth value clamping", { "VK_EXT_depth_clamp_zero_one", "Features.fragmentStoresAndAtomics", "Features.depthClamp" }, false },
157 { "out_of_range", "Test late clamping of out-of-range depth values", { "VK_EXT_depth_clamp_zero_one" }, false },
158 { "ez_fs_clamp", "Test fragment shader depth value with early fragment tests", { "VK_EXT_depth_clamp_zero_one", "Features.fragmentStoresAndAtomics", "Features.depthClamp" }, false },
159 { "bias_fs_clamp", "Test fragment shader depth value with depthBias enabled", { "VK_EXT_depth_clamp_zero_one", "Features.fragmentStoresAndAtomics", "Features.depthClamp" }, false },
160 { "bias_outside_range", "Test biasing depth values out of the depth range", { "VK_EXT_depth_clamp_zero_one", "Features.fragmentStoresAndAtomics" }, false },
161 { "bias_outside_range_fs_clamp", "Test fragment shader depth value when biasing out of range", { "VK_EXT_depth_clamp_zero_one", "Features.fragmentStoresAndAtomics" }, false },
162
163 // Rerun any tests that will get different results with VK_EXT_depth_range_unrestricted
164 { "out_of_range_unrestricted", "Test late clamping of out-of-range depth values", { "VK_EXT_depth_clamp_zero_one" }, true },
165 { "bias_outside_range_fs_clamp_unrestricted", "Test fragment shader depth value when biasing out of range", { "VK_EXT_depth_clamp_zero_one", "Features.fragmentStoresAndAtomics" }, true },
166 };
167
168 tcu::TestContext& testCtx = g->getTestContext();
169
170 for (const auto& test : tests)
171 {
172 g->addChild(createDepthTestCase(testCtx, test, g->getName(), test.name + ".amber"));
173 }
174 }
175
cleanupGroup(tcu::TestCaseGroup *)176 static void cleanupGroup(tcu::TestCaseGroup*)
177 {
178 // Destroy custom device object
179 g_singletonDeviceDepthGroup.clear();
180 }
181
createAmberDepthGroup(tcu::TestContext & testCtx)182 tcu::TestCaseGroup* createAmberDepthGroup (tcu::TestContext& testCtx)
183 {
184 return createTestGroup(testCtx, "depth", "Depth pipeline test group", createTests, cleanupGroup);
185 }
186
187 } // cts_amber
188 } // vkt
189