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& params, tcu::TestContext& testCtx, tcu::TestCaseGroup* group)
46 {
47 group->addChild(new SparseCase(testCtx, params.name, params.function, params.imageType, params.imageSize, params.format, params.operand));
48 }
49
createSparseResourcesShaderIntrinsicsTests(tcu::TestContext & testCtx)50 tcu::TestCaseGroup* createSparseResourcesShaderIntrinsicsTests (tcu::TestContext& testCtx)
51 {
52 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "shader_intrinsics", "Sparse Resources Shader Intrinsics"));
53
54 const std::vector<TestImageParameters> imageParameters
55 {
56 { IMAGE_TYPE_2D, { tcu::UVec3(512u, 256u, 1u), tcu::UVec3(128u, 128u, 1u), tcu::UVec3(503u, 137u, 1u), tcu::UVec3(11u, 37u, 1u) }, getTestFormats(IMAGE_TYPE_2D) },
57 { IMAGE_TYPE_2D_ARRAY, { tcu::UVec3(512u, 256u, 6u), tcu::UVec3(128u, 128u, 8u), tcu::UVec3(503u, 137u, 3u), tcu::UVec3(11u, 37u, 3u) }, getTestFormats(IMAGE_TYPE_2D_ARRAY) },
58 { IMAGE_TYPE_CUBE, { tcu::UVec3(256u, 256u, 1u), tcu::UVec3(128u, 128u, 1u), tcu::UVec3(137u, 137u, 1u), tcu::UVec3(11u, 11u, 1u) }, getTestFormats(IMAGE_TYPE_CUBE) },
59 { IMAGE_TYPE_CUBE_ARRAY, { tcu::UVec3(256u, 256u, 6u), tcu::UVec3(128u, 128u, 8u), tcu::UVec3(137u, 137u, 3u), tcu::UVec3(11u, 11u, 3u) }, getTestFormats(IMAGE_TYPE_CUBE_ARRAY) },
60 { IMAGE_TYPE_3D, { tcu::UVec3(256u, 256u, 16u), tcu::UVec3(128u, 128u, 8u), tcu::UVec3(503u, 137u, 3u), tcu::UVec3(11u, 37u, 3u) }, getTestFormats(IMAGE_TYPE_3D) }
61 };
62
63 static const std::string functions[SPARSE_SPIRV_FUNCTION_TYPE_LAST]
64 {
65 "_sparse_fetch",
66 "_sparse_read",
67 "_sparse_sample_explicit_lod",
68 "_sparse_sample_implicit_lod",
69 "_sparse_gather",
70 };
71
72 // store functions constructing cases in a map to avoid switch in a loop
73 typedef void(*AddSparseCaseFun)(const SparseCaseParams&, tcu::TestContext&, tcu::TestCaseGroup*);
74 const std::map<SpirVFunction, AddSparseCaseFun> sparseCaseFunMap
75 {
76 { SPARSE_FETCH, &addSparseCase<SparseCaseOpImageSparseFetch> },
77 { SPARSE_READ, &addSparseCase<SparseCaseOpImageSparseRead> },
78 { SPARSE_SAMPLE_EXPLICIT_LOD, &addSparseCase<SparseCaseOpImageSparseSampleExplicitLod> },
79 { SPARSE_SAMPLE_IMPLICIT_LOD, &addSparseCase<SparseCaseOpImageSparseSampleImplicitLod> },
80 { SPARSE_GATHER, &addSparseCase<SparseCaseOpImageSparseGather> }
81 };
82
83 SparseCaseParams caseParams;
84
85 for (deUint32 functionNdx = 0; functionNdx < SPARSE_SPIRV_FUNCTION_TYPE_LAST; ++functionNdx)
86 {
87 caseParams.function = static_cast<SpirVFunction>(functionNdx);
88
89 // grab function that should be used to construct case of proper type
90 auto addCaseFunctionPtr = sparseCaseFunMap.at(caseParams.function);
91
92 for (const auto& imageParams : imageParameters)
93 {
94 caseParams.imageType = imageParams.imageType;
95
96 de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, (getImageTypeName(caseParams.imageType) + functions[functionNdx]).c_str(), ""));
97
98 for (const auto& testFormat : imageParams.formats)
99 {
100 caseParams.format = testFormat.format;
101
102 tcu::UVec3 imageSizeAlignment = getImageSizeAlignment(caseParams.format);
103 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, getImageFormatID(caseParams.format).c_str(), ""));
104
105 for (size_t imageSizeNdx = 0; imageSizeNdx < imageParams.imageSizes.size(); ++imageSizeNdx)
106 {
107 caseParams.imageSize = imageParams.imageSizes[imageSizeNdx];
108
109 // skip test for images with odd sizes for some YCbCr formats
110 if (((caseParams.imageSize.x() % imageSizeAlignment.x()) != 0) ||
111 ((caseParams.imageSize.y() % imageSizeAlignment.y()) != 0))
112 continue;
113
114 // skip cases depending on image type
115 switch (caseParams.function)
116 {
117 case SPARSE_FETCH:
118 if ((caseParams.imageType == IMAGE_TYPE_CUBE) || (caseParams.imageType == IMAGE_TYPE_CUBE_ARRAY))
119 continue;
120 break;
121 case SPARSE_SAMPLE_EXPLICIT_LOD:
122 case SPARSE_SAMPLE_IMPLICIT_LOD:
123 case SPARSE_GATHER:
124 if ((caseParams.imageType == IMAGE_TYPE_CUBE) || (caseParams.imageType == IMAGE_TYPE_CUBE_ARRAY) || (caseParams.imageType == IMAGE_TYPE_3D))
125 continue;
126 break;
127 default:
128 break;
129 }
130
131 std::ostringstream nameStream;
132 nameStream << caseParams.imageSize.x() << "_" << caseParams.imageSize.y() << "_" << caseParams.imageSize.z();
133 caseParams.name = nameStream.str();
134
135 caseParams.operand = "";
136 (*addCaseFunctionPtr)(caseParams, testCtx, formatGroup.get());
137
138 // duplicate tests with Nontemporal operand just for smallest size (which is the last one)
139 if (imageSizeNdx == (imageParams.imageSizes.size() - 1))
140 {
141 caseParams.operand = "Nontemporal";
142 caseParams.name += "_nontemporal";
143 (*addCaseFunctionPtr)(caseParams, testCtx, formatGroup.get());
144 }
145 }
146 imageTypeGroup->addChild(formatGroup.release());
147 }
148 testGroup->addChild(imageTypeGroup.release());
149 }
150 }
151
152 return testGroup.release();
153 }
154
155 } // sparse
156 } // vkt
157