1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*
20 * \file vktSparseResourcesShaderIntrinsics.cpp
21 * \brief Sparse Resources Shader Intrinsics
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktSparseResourcesShaderIntrinsicsSampled.hpp"
25 #include "vktSparseResourcesShaderIntrinsicsStorage.hpp"
26
27 using namespace vk;
28
29 namespace vkt
30 {
31 namespace sparse
32 {
33
34 struct SparseCaseParams
35 {
36 std::string name;
37 SpirVFunction function;
38 ImageType imageType;
39 tcu::UVec3 imageSize;
40 vk::VkFormat format;
41 std::string operand;
42 };
43
44 template <typename SparseCase>
addSparseCase(const SparseCaseParams & params,tcu::TestContext & testCtx,tcu::TestCaseGroup * group)45 void addSparseCase(const SparseCaseParams ¶ms, tcu::TestContext &testCtx, tcu::TestCaseGroup *group)
46 {
47 group->addChild(new SparseCase(testCtx, params.name, params.function, params.imageType, params.imageSize,
48 params.format, params.operand));
49 }
50
createSparseResourcesShaderIntrinsicsTests(tcu::TestContext & testCtx)51 tcu::TestCaseGroup *createSparseResourcesShaderIntrinsicsTests(tcu::TestContext &testCtx)
52 {
53 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "shader_intrinsics"));
54
55 const std::vector<TestImageParameters> imageParameters{
56 {IMAGE_TYPE_2D,
57 {tcu::UVec3(512u, 256u, 1u), tcu::UVec3(128u, 128u, 1u), tcu::UVec3(503u, 137u, 1u), tcu::UVec3(11u, 37u, 1u)},
58 getTestFormats(IMAGE_TYPE_2D)},
59 {IMAGE_TYPE_2D_ARRAY,
60 {tcu::UVec3(512u, 256u, 6u), tcu::UVec3(128u, 128u, 8u), tcu::UVec3(503u, 137u, 3u), tcu::UVec3(11u, 37u, 3u)},
61 getTestFormats(IMAGE_TYPE_2D_ARRAY)},
62 {IMAGE_TYPE_CUBE,
63 {tcu::UVec3(256u, 256u, 1u), tcu::UVec3(128u, 128u, 1u), tcu::UVec3(137u, 137u, 1u), tcu::UVec3(11u, 11u, 1u)},
64 getTestFormats(IMAGE_TYPE_CUBE)},
65 {IMAGE_TYPE_CUBE_ARRAY,
66 {tcu::UVec3(256u, 256u, 6u), tcu::UVec3(128u, 128u, 8u), tcu::UVec3(137u, 137u, 3u), tcu::UVec3(11u, 11u, 3u)},
67 getTestFormats(IMAGE_TYPE_CUBE_ARRAY)},
68 {IMAGE_TYPE_3D,
69 {tcu::UVec3(256u, 256u, 16u), tcu::UVec3(128u, 128u, 8u), tcu::UVec3(503u, 137u, 3u),
70 tcu::UVec3(11u, 37u, 3u)},
71 getTestFormats(IMAGE_TYPE_3D)}};
72
73 static const std::string functions[SPARSE_SPIRV_FUNCTION_TYPE_LAST]{
74 "_sparse_fetch", "_sparse_read", "_sparse_sample_explicit_lod", "_sparse_sample_implicit_lod", "_sparse_gather",
75 };
76
77 // store functions constructing cases in a map to avoid switch in a loop
78 typedef void (*AddSparseCaseFun)(const SparseCaseParams &, tcu::TestContext &, tcu::TestCaseGroup *);
79 const std::map<SpirVFunction, AddSparseCaseFun> sparseCaseFunMap{
80 {SPARSE_FETCH, &addSparseCase<SparseCaseOpImageSparseFetch>},
81 {SPARSE_READ, &addSparseCase<SparseCaseOpImageSparseRead>},
82 {SPARSE_SAMPLE_EXPLICIT_LOD, &addSparseCase<SparseCaseOpImageSparseSampleExplicitLod>},
83 {SPARSE_SAMPLE_IMPLICIT_LOD, &addSparseCase<SparseCaseOpImageSparseSampleImplicitLod>},
84 {SPARSE_GATHER, &addSparseCase<SparseCaseOpImageSparseGather>}};
85
86 SparseCaseParams caseParams;
87
88 for (uint32_t functionNdx = 0; functionNdx < SPARSE_SPIRV_FUNCTION_TYPE_LAST; ++functionNdx)
89 {
90 caseParams.function = static_cast<SpirVFunction>(functionNdx);
91
92 // grab function that should be used to construct case of proper type
93 auto addCaseFunctionPtr = sparseCaseFunMap.at(caseParams.function);
94
95 for (const auto &imageParams : imageParameters)
96 {
97 caseParams.imageType = imageParams.imageType;
98
99 de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(
100 testCtx, (getImageTypeName(caseParams.imageType) + functions[functionNdx]).c_str()));
101
102 for (const auto &testFormat : imageParams.formats)
103 {
104 caseParams.format = testFormat.format;
105
106 tcu::UVec3 imageSizeAlignment = getImageSizeAlignment(caseParams.format);
107 de::MovePtr<tcu::TestCaseGroup> formatGroup(
108 new tcu::TestCaseGroup(testCtx, getImageFormatID(caseParams.format).c_str()));
109
110 for (size_t imageSizeNdx = 0; imageSizeNdx < imageParams.imageSizes.size(); ++imageSizeNdx)
111 {
112 caseParams.imageSize = imageParams.imageSizes[imageSizeNdx];
113
114 // skip test for images with odd sizes for some YCbCr formats
115 if (((caseParams.imageSize.x() % imageSizeAlignment.x()) != 0) ||
116 ((caseParams.imageSize.y() % imageSizeAlignment.y()) != 0))
117 continue;
118
119 // skip cases depending on image type
120 switch (caseParams.function)
121 {
122 case SPARSE_FETCH:
123 if ((caseParams.imageType == IMAGE_TYPE_CUBE) ||
124 (caseParams.imageType == IMAGE_TYPE_CUBE_ARRAY))
125 continue;
126 break;
127 case SPARSE_SAMPLE_EXPLICIT_LOD:
128 case SPARSE_SAMPLE_IMPLICIT_LOD:
129 case SPARSE_GATHER:
130 if ((caseParams.imageType == IMAGE_TYPE_CUBE) ||
131 (caseParams.imageType == IMAGE_TYPE_CUBE_ARRAY) || (caseParams.imageType == IMAGE_TYPE_3D))
132 continue;
133 break;
134 default:
135 break;
136 }
137
138 std::ostringstream nameStream;
139 nameStream << caseParams.imageSize.x() << "_" << caseParams.imageSize.y() << "_"
140 << caseParams.imageSize.z();
141 caseParams.name = nameStream.str();
142
143 caseParams.operand = "";
144 (*addCaseFunctionPtr)(caseParams, testCtx, formatGroup.get());
145
146 // duplicate tests with Nontemporal operand just for smallest size (which is the last one)
147 if (imageSizeNdx == (imageParams.imageSizes.size() - 1))
148 {
149 caseParams.operand = "Nontemporal";
150 caseParams.name += "_nontemporal";
151 (*addCaseFunctionPtr)(caseParams, testCtx, formatGroup.get());
152 }
153 }
154 imageTypeGroup->addChild(formatGroup.release());
155 }
156 testGroup->addChild(imageTypeGroup.release());
157 }
158 }
159
160 return testGroup.release();
161 }
162
163 } // namespace sparse
164 } // namespace vkt
165