xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsTestsUtils.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _VKTSUBGROUPSTESTSUTILS_HPP
2 #define _VKTSUBGROUPSTESTSUTILS_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2017 The Khronos Group Inc.
8  * Copyright (c) 2017 Codeplay Software Ltd.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */ /*!
23  * \file
24  * \brief Subgroups tests utility classes
25  */ /*--------------------------------------------------------------------*/
26 
27 #include "vkBuilderUtil.hpp"
28 #include "vkDefs.hpp"
29 #include "vkDeviceUtil.hpp"
30 #include "vkMemUtil.hpp"
31 #include "vkPlatform.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkRef.hpp"
35 #include "vkRefUtil.hpp"
36 #include "vkStrUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vktTestCase.hpp"
39 #include "vktTestCaseUtil.hpp"
40 #include "vkRayTracingUtil.hpp"
41 
42 #include "tcuFormatUtil.hpp"
43 #include "tcuTestLog.hpp"
44 #include "tcuVectorUtil.hpp"
45 
46 #include "gluShaderUtil.hpp"
47 
48 #include "deSharedPtr.hpp"
49 #include "deUniquePtr.hpp"
50 
51 #include <string>
52 #include <vector>
53 
54 namespace vkt
55 {
56 namespace subgroups
57 {
58 typedef bool (*CheckResult)(const void *internalData, std::vector<const void *> datas, uint32_t width,
59                             uint32_t subgroupSize);
60 typedef bool (*CheckResultFragment)(const void *internalData, std::vector<const void *> datas, uint32_t width,
61                                     uint32_t height, uint32_t subgroupSize);
62 typedef bool (*CheckResultCompute)(const void *internalData, std::vector<const void *> datas,
63                                    const uint32_t numWorkgroups[3], const uint32_t localSize[3], uint32_t subgroupSize);
64 
65 // A struct to represent input data to a shader
66 struct SSBOData
67 {
68     enum InputDataInitializeType
69     {
70         InitializeNone = 0,
71         InitializeNonZero,
72         InitializeZero,
73     };
74     enum InputDataLayoutType
75     {
76         LayoutStd140 = 0,
77         LayoutStd430,
78         LayoutPacked
79     };
80 
81     enum BindingType
82     {
83         BindingSSBO,
84         BindingImage,
85         BindingUBO,
86     };
87 
SSBODatavkt::subgroups::SSBOData88     SSBOData()
89         : initializeType(InitializeNone)
90         , layout(LayoutStd140)
91         , format(vk::VK_FORMAT_UNDEFINED)
92         , numElements(0)
93         , bindingType(BindingSSBO)
94         , binding(0u)
95         , stages((vk::VkShaderStageFlags)0u)
96     {
97     }
98 
SSBODatavkt::subgroups::SSBOData99     SSBOData(InputDataInitializeType initializeType_, InputDataLayoutType layout_, vk::VkFormat format_,
100              vk::VkDeviceSize numElements_, BindingType bindingType_ = BindingSSBO, uint32_t binding_ = 0u,
101              vk::VkShaderStageFlags stages_ = static_cast<vk::VkShaderStageFlags>(0u))
102         : initializeType(initializeType_)
103         , layout(layout_)
104         , format(format_)
105         , numElements(numElements_)
106         , bindingType(bindingType_)
107         , binding(binding_)
108         , stages(stages_)
109     {
110         if (bindingType == BindingUBO)
111             DE_ASSERT(layout == LayoutStd140);
112     }
113 
isImagevkt::subgroups::SSBOData114     bool isImage() const
115     {
116         return (bindingType == BindingImage);
117     }
118 
isUBOvkt::subgroups::SSBOData119     bool isUBO() const
120     {
121         return (bindingType == BindingUBO);
122     }
123 
124     InputDataInitializeType initializeType;
125     InputDataLayoutType layout;
126     vk::VkFormat format;
127     vk::VkDeviceSize numElements;
128     BindingType bindingType;
129     uint32_t binding;
130     vk::VkShaderStageFlags stages;
131 };
132 
133 uint32_t getStagesCount(vk::VkShaderStageFlags shaderStages);
134 
135 std::string getSharedMemoryBallotHelper();
136 
137 std::string getSharedMemoryBallotHelperARB();
138 
139 uint32_t getSubgroupSize(Context &context);
140 
141 uint32_t maxSupportedSubgroupSize();
142 
143 std::string getShaderStageName(vk::VkShaderStageFlags stage);
144 
145 std::string getSubgroupFeatureName(vk::VkSubgroupFeatureFlagBits bit);
146 
147 void addNoSubgroupShader(vk::SourceCollections &programCollection);
148 
149 void initStdFrameBufferPrograms(vk::SourceCollections &programCollection, const vk::ShaderBuildOptions &buildOptions,
150                                 vk::VkShaderStageFlags shaderStage, vk::VkFormat format, bool gsPointSize,
151                                 const std::string &extHeader, const std::string &testSrc, const std::string &helperStr,
152                                 const std::vector<std::string> &declarations = std::vector<std::string>());
153 
154 void initStdPrograms(vk::SourceCollections &programCollection, const vk::ShaderBuildOptions &buildOptions,
155                      vk::VkShaderStageFlags shaderStage, vk::VkFormat format, bool gsPointSize,
156                      const std::string &extHeader, const std::string &testSrc, const std::string &helperStr,
157                      const std::vector<std::string> &declarations = std::vector<std::string>(),
158                      const bool avoidHelperInvocations = false, const std::string &tempRes = "  uint tempRes;\n");
159 
160 bool isSubgroupSupported(Context &context);
161 
162 bool areSubgroupOperationsSupportedForStage(Context &context, vk::VkShaderStageFlags stage);
163 
164 bool isSubgroupFeatureSupportedForDevice(Context &context, vk::VkSubgroupFeatureFlagBits bit);
165 
166 bool areQuadOperationsSupportedForStages(Context &context, const vk::VkShaderStageFlags stages);
167 
168 bool isFragmentSSBOSupportedForDevice(Context &context);
169 
170 bool isVertexSSBOSupportedForDevice(Context &context);
171 
172 bool isFormatSupportedForDevice(Context &context, vk::VkFormat format);
173 
174 bool isInt64SupportedForDevice(Context &context);
175 
176 bool isTessellationAndGeometryPointSizeSupported(Context &context);
177 
178 bool is16BitUBOStorageSupported(Context &context);
179 
180 bool is8BitUBOStorageSupported(Context &context);
181 
182 bool isSubgroupBroadcastDynamicIdSupported(Context &context);
183 
184 bool isSubgroupRotateSpecVersionValid(Context &context);
185 
186 std::string getFormatNameForGLSL(vk::VkFormat format);
187 
188 std::string getAdditionalExtensionForFormat(vk::VkFormat format);
189 
190 const std::vector<vk::VkFormat> getAllFormats();
191 
192 bool isFormatSigned(vk::VkFormat format);
193 bool isFormatUnsigned(vk::VkFormat format);
194 bool isFormatFloat(vk::VkFormat format);
195 bool isFormatBool(vk::VkFormat format);
196 bool isFormat8bitTy(vk::VkFormat format);
197 bool isFormat16BitTy(vk::VkFormat format);
198 
199 void addGeometryShadersFromTemplate(const std::string &glslTemplate, const vk::ShaderBuildOptions &options,
200                                     vk::GlslSourceCollection &collection);
201 void addGeometryShadersFromTemplate(const std::string &spirvTemplate, const vk::SpirVAsmBuildOptions &options,
202                                     vk::SpirVAsmCollection &collection);
203 
204 void setVertexShaderFrameBuffer(vk::SourceCollections &programCollection);
205 
206 void setFragmentShaderFrameBuffer(vk::SourceCollections &programCollection);
207 
208 void setFragmentShaderFrameBuffer(vk::SourceCollections &programCollection);
209 
210 void setTesCtrlShaderFrameBuffer(vk::SourceCollections &programCollection);
211 
212 void setTesEvalShaderFrameBuffer(vk::SourceCollections &programCollection);
213 
214 bool check(std::vector<const void *> datas, uint32_t width, uint32_t ref);
215 
216 bool checkComputeOrMesh(std::vector<const void *> datas, const uint32_t numWorkgroups[3], const uint32_t localSize[3],
217                         uint32_t ref);
218 
219 tcu::TestStatus makeTessellationEvaluationFrameBufferTest(
220     Context &context, vk::VkFormat format, const SSBOData *extraData, uint32_t extraDataCount, const void *internalData,
221     CheckResult checkResult, const vk::VkShaderStageFlags shaderStage = vk::VK_SHADER_STAGE_ALL_GRAPHICS);
222 
223 tcu::TestStatus makeGeometryFrameBufferTest(Context &context, vk::VkFormat format, const SSBOData *extraData,
224                                             uint32_t extraDataCount, const void *internalData, CheckResult checkResult);
225 
226 // Allows using verification functions with or without the optional last boolean argument.
227 // If using a function that does not need the last argument, it will not be passed down to it.
228 class VerificationFunctor
229 {
230 public:
231     using NoLastArgVariant = bool (*)(const void *, std::vector<const void *>, uint32_t, uint32_t);
232     using AllArgsVariant   = bool (*)(const void *, std::vector<const void *>, uint32_t, uint32_t, bool);
233 
VerificationFunctor(NoLastArgVariant func)234     VerificationFunctor(NoLastArgVariant func) : m_noLastArgFunc{func}, m_allArgsFunc{nullptr}
235     {
236     }
237 
VerificationFunctor(AllArgsVariant func)238     VerificationFunctor(AllArgsVariant func) : m_noLastArgFunc{nullptr}, m_allArgsFunc{func}
239     {
240     }
241 
operator ()(const void * extraData,std::vector<const void * > datas,uint32_t width,uint32_t subgroupSize,bool multipleCallsPossible) const242     bool operator()(const void *extraData, std::vector<const void *> datas, uint32_t width, uint32_t subgroupSize,
243                     bool multipleCallsPossible) const
244     {
245         if (m_allArgsFunc)
246             return m_allArgsFunc(extraData, datas, width, subgroupSize, multipleCallsPossible);
247         return m_noLastArgFunc(extraData, datas, width, subgroupSize);
248     }
249 
250 private:
251     NoLastArgVariant m_noLastArgFunc;
252     AllArgsVariant m_allArgsFunc;
253 };
254 
255 vk::VkShaderStageFlags getPossibleGraphicsSubgroupStages(Context &context, const vk::VkShaderStageFlags testedStages);
256 
257 tcu::TestStatus allStages(Context &context, vk::VkFormat format, const SSBOData *extraData, uint32_t extraDataCount,
258                           const void *internalData, const VerificationFunctor &checkResult,
259                           const vk::VkShaderStageFlags shaderStage);
260 
261 tcu::TestStatus makeVertexFrameBufferTest(Context &context, vk::VkFormat format, const SSBOData *extraData,
262                                           uint32_t extraDataCount, const void *internalData, CheckResult checkResult);
263 
264 tcu::TestStatus makeFragmentFrameBufferTest(Context &context, vk::VkFormat format, const SSBOData *extraData,
265                                             uint32_t extraDataCount, const void *internalData,
266                                             CheckResultFragment checkResult);
267 
268 tcu::TestStatus makeComputeTest(Context &context, vk::VkFormat format, const SSBOData *inputs, uint32_t inputsCount,
269                                 const void *internalData, CheckResultCompute checkResult,
270                                 uint32_t requiredSubgroupSize = 0u, const uint32_t pipelineShaderStageCreateFlags = 0u);
271 
272 tcu::TestStatus makeMeshTest(Context &context, vk::VkFormat format, const SSBOData *inputs, uint32_t inputsCount,
273                              const void *internalData, CheckResultCompute checkResult,
274                              uint32_t requiredSubgroupSize = 0u, const uint32_t pipelineShaderStageCreateFlags = 0u);
275 
276 /* Functions needed for VK_EXT_subgroup_size_control tests */
277 tcu::TestStatus makeTessellationEvaluationFrameBufferTestRequiredSubgroupSize(
278     Context &context, vk::VkFormat format, const SSBOData *extraData, uint32_t extraDataCount, const void *internalData,
279     CheckResult checkResult, const vk::VkShaderStageFlags shaderStage = vk::VK_SHADER_STAGE_ALL_GRAPHICS,
280     const uint32_t tessShaderStageCreateFlags = 0u, const uint32_t requiredSubgroupSize = 0u);
281 
282 tcu::TestStatus makeGeometryFrameBufferTestRequiredSubgroupSize(Context &context, vk::VkFormat format,
283                                                                 const SSBOData *extraData, uint32_t extraDataCount,
284                                                                 const void *internalData, CheckResult checkResult,
285                                                                 const uint32_t geometryShaderStageCreateFlags = 0u,
286                                                                 const uint32_t requiredSubgroupSize           = 0u);
287 
288 tcu::TestStatus allStagesRequiredSubgroupSize(
289     Context &context, vk::VkFormat format, const SSBOData *extraDatas, uint32_t extraDatasCount,
290     const void *internalData, const VerificationFunctor &checkResult, const vk::VkShaderStageFlags shaderStageTested,
291     const uint32_t vertexShaderStageCreateFlags, const uint32_t tessellationControlShaderStageCreateFlags,
292     const uint32_t tessellationEvalShaderStageCreateFlags, const uint32_t geometryShaderStageCreateFlags,
293     const uint32_t fragmentShaderStageCreateFlags, const uint32_t requiredSubgroupSize[5]);
294 
295 tcu::TestStatus makeVertexFrameBufferTestRequiredSubgroupSize(Context &context, vk::VkFormat format,
296                                                               const SSBOData *extraData, uint32_t extraDataCount,
297                                                               const void *internalData, CheckResult checkResult,
298                                                               const uint32_t vertexShaderStageCreateFlags = 0u,
299                                                               const uint32_t requiredSubgroupSize         = 0u);
300 
301 tcu::TestStatus makeFragmentFrameBufferTestRequiredSubgroupSize(Context &context, vk::VkFormat format,
302                                                                 const SSBOData *extraData, uint32_t extraDataCount,
303                                                                 const void *internalData,
304                                                                 CheckResultFragment checkResult,
305                                                                 const uint32_t fragmentShaderStageCreateFlags = 0u,
306                                                                 const uint32_t requiredSubgroupSize           = 0u);
307 
308 tcu::TestStatus makeComputeTestRequiredSubgroupSize(Context &context, vk::VkFormat format, const SSBOData *inputs,
309                                                     uint32_t inputsCount, const void *internalData,
310                                                     CheckResultCompute checkResult,
311                                                     const uint32_t pipelineShaderStageCreateFlags,
312                                                     const uint32_t numWorkgroups[3], const bool isRequiredSubgroupSize,
313                                                     const uint32_t subgroupSize, const uint32_t localSizesToTest[][3],
314                                                     const uint32_t localSizesToTestCount);
315 
316 tcu::TestStatus makeMeshTestRequiredSubgroupSize(Context &context, vk::VkFormat format, const SSBOData *inputs,
317                                                  uint32_t inputsCount, const void *internalData,
318                                                  CheckResultCompute checkResult,
319                                                  const uint32_t pipelineShaderStageCreateFlags,
320                                                  const uint32_t numWorkgroups[3], const bool isRequiredSubgroupSize,
321                                                  const uint32_t subgroupSize, const uint32_t localSizesToTest[][3],
322                                                  const uint32_t localSizesToTestCount);
323 
324 void supportedCheckShader(Context &context, const vk::VkShaderStageFlags shaderStage);
325 
326 const std::vector<vk::VkFormat> getAllRayTracingFormats();
327 
328 void addRayTracingNoSubgroupShader(vk::SourceCollections &programCollection);
329 
330 vk::VkShaderStageFlags getPossibleRayTracingSubgroupStages(Context &context, const vk::VkShaderStageFlags testedStages);
331 
332 tcu::TestStatus allRayTracingStages(Context &context, vk::VkFormat format, const SSBOData *extraData,
333                                     uint32_t extraDataCount, const void *internalData,
334                                     const VerificationFunctor &checkResult, const vk::VkShaderStageFlags shaderStage);
335 
336 tcu::TestStatus allRayTracingStagesRequiredSubgroupSize(
337     Context &context, vk::VkFormat format, const SSBOData *extraDatas, uint32_t extraDatasCount,
338     const void *internalData, const VerificationFunctor &checkResult, const vk::VkShaderStageFlags shaderStageTested,
339     const uint32_t shaderStageCreateFlags[6], const uint32_t requiredSubgroupSize[6]);
340 } // namespace subgroups
341 } // namespace vkt
342 
343 #endif // _VKTSUBGROUPSTESTSUTILS_HPP
344