1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2023 LunarG, Inc.
6 * Copyright (c) 2023 Nintendo
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 Shader Object Binary Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktShaderObjectBinaryTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vktShaderObjectCreateUtil.hpp"
30 #include "vktCustomInstancesDevices.hpp"
31 #include "tcuTestLog.hpp"
32 #include "deRandom.hpp"
33 #include "tcuCommandLine.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkQueryUtil.hpp"
36
37 #include <cmath>
38
39 namespace vkt
40 {
41 namespace ShaderObject
42 {
43
44 namespace
45 {
46
47 enum QueryType
48 {
49 SAME_SHADER,
50 NEW_SHADER,
51 SHADER_FROM_BINARY,
52 NEW_DEVICE,
53 DEVICE_NO_EXTS_FEATURES,
54 ALL_FEATURE_COMBINATIONS,
55 };
56
57 struct TestParams
58 {
59 vk::VkShaderStageFlagBits stage;
60 bool linked;
61 QueryType queryType;
62 };
63
64 enum IncompleteBinaryTestType
65 {
66 HALF_DATA_SIZE,
67 GARBAGE_DATA,
68 GARBAGE_SECOND_HALF,
69 CREATE_FROM_HALF_SIZE,
70 CREATE_FROM_HALF_SIZE_GARBAGE,
71 };
72
getNextStage(vk::VkShaderStageFlagBits shaderStage,bool tessellationShaderFeature,bool geometryShaderFeature)73 vk::VkShaderStageFlags getNextStage(vk::VkShaderStageFlagBits shaderStage, bool tessellationShaderFeature,
74 bool geometryShaderFeature)
75 {
76 if (shaderStage == vk::VK_SHADER_STAGE_VERTEX_BIT)
77 {
78 if (tessellationShaderFeature)
79 return vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
80 else if (geometryShaderFeature)
81 return vk::VK_SHADER_STAGE_GEOMETRY_BIT;
82 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
83 }
84 else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
85 {
86 return vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
87 }
88 else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
89 {
90 if (geometryShaderFeature)
91 return vk::VK_SHADER_STAGE_GEOMETRY_BIT;
92 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
93 }
94 else if (shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
95 {
96 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
97 }
98 return 0u;
99 }
100
createShader(const vk::DeviceInterface & vk,const vk::BinaryCollection & binaries,const vk::VkDevice device,vk::VkPhysicalDeviceFeatures features,vk::VkDescriptorSetLayout descriptorSetLayout,bool linked,vk::VkShaderStageFlagBits stage)101 vk::Move<vk::VkShaderEXT> createShader(const vk::DeviceInterface &vk, const vk::BinaryCollection &binaries,
102 const vk::VkDevice device, vk::VkPhysicalDeviceFeatures features,
103 vk::VkDescriptorSetLayout descriptorSetLayout, bool linked,
104 vk::VkShaderStageFlagBits stage)
105 {
106 vk::VkShaderEXT shader;
107
108 if (!linked)
109 {
110 const auto &src = binaries.get(vk::getShaderName(stage));
111 const vk::VkShaderCreateInfoEXT shaderCreateInfo = {
112 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
113 DE_NULL, // const void* pNext;
114 0u, // VkShaderCreateFlagsEXT flags;
115 stage, // VkShaderStageFlagBits stage;
116 getNextStage(stage, features.tessellationShader,
117 features.geometryShader), // VkShaderStageFlags nextStage;
118 vk::VK_SHADER_CODE_TYPE_SPIRV_EXT, // VkShaderCodeTypeEXT codeType;
119 src.getSize(), // size_t codeSize;
120 src.getBinary(), // const void* pCode;
121 "main", // const char* pName;
122 (descriptorSetLayout != VK_NULL_HANDLE) ? 1u : 0u, // uint32_t setLayoutCount;
123 (descriptorSetLayout != VK_NULL_HANDLE) ? &descriptorSetLayout :
124 DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
125 0u, // uint32_t pushConstantRangeCount;
126 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
127 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
128 };
129
130 vk.createShadersEXT(device, 1u, &shaderCreateInfo, DE_NULL, &shader);
131 }
132 else
133 {
134 const auto &vert = binaries.get("vert");
135 const auto &tesc = binaries.get("tesc");
136 const auto &tese = binaries.get("tese");
137 const auto &geom = binaries.get("geom");
138 const auto &frag = binaries.get("frag");
139
140 std::vector<vk::VkShaderCreateInfoEXT> shaderCreateInfos = {
141 {
142 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
143 DE_NULL, // const void* pNext;
144 vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT, // VkShaderCreateFlagsEXT flags;
145 vk::VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
146 getNextStage(vk::VK_SHADER_STAGE_VERTEX_BIT, features.tessellationShader,
147 features.geometryShader), // VkShaderStageFlags nextStage;
148 vk::VK_SHADER_CODE_TYPE_SPIRV_EXT, // VkShaderCodeTypeEXT codeType;
149 vert.getSize(), // size_t codeSize;
150 vert.getBinary(), // const void* pCode;
151 "main", // const char* pName;
152 0u, // uint32_t setLayoutCount;
153 DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
154 0u, // uint32_t pushConstantRangeCount;
155 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
156 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
157 },
158 {
159 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
160 DE_NULL, // const void* pNext;
161 vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT, // VkShaderCreateFlagsEXT flags;
162 vk::VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
163 getNextStage(vk::VK_SHADER_STAGE_FRAGMENT_BIT, features.tessellationShader,
164 features.geometryShader), // VkShaderStageFlags nextStage;
165 vk::VK_SHADER_CODE_TYPE_SPIRV_EXT, // VkShaderCodeTypeEXT codeType;
166 frag.getSize(), // size_t codeSize;
167 frag.getBinary(), // const void* pCode;
168 "main", // const char* pName;
169 0u, // uint32_t setLayoutCount;
170 DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
171 0u, // uint32_t pushConstantRangeCount;
172 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
173 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
174 },
175 };
176 if (features.tessellationShader)
177 {
178 shaderCreateInfos.push_back({
179 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
180 DE_NULL, // const void* pNext;
181 vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT, // VkShaderCreateFlagsEXT flags;
182 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlagBits stage;
183 getNextStage(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, features.tessellationShader,
184 features.geometryShader), // VkShaderStageFlags nextStage;
185 vk::VK_SHADER_CODE_TYPE_SPIRV_EXT, // VkShaderCodeTypeEXT codeType;
186 tesc.getSize(), // size_t codeSize;
187 tesc.getBinary(), // const void* pCode;
188 "main", // const char* pName;
189 0u, // uint32_t setLayoutCount;
190 DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
191 0u, // uint32_t pushConstantRangeCount;
192 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
193 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
194 });
195 shaderCreateInfos.push_back({
196 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
197 DE_NULL, // const void* pNext;
198 vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT, // VkShaderCreateFlagsEXT flags;
199 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // VkShaderStageFlagBits stage;
200 getNextStage(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, features.tessellationShader,
201 features.geometryShader), // VkShaderStageFlags nextStage;
202 vk::VK_SHADER_CODE_TYPE_SPIRV_EXT, // VkShaderCodeTypeEXT codeType;
203 tese.getSize(), // size_t codeSize;
204 tese.getBinary(), // const void* pCode;
205 "main", // const char* pName;
206 0u, // uint32_t setLayoutCount;
207 DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
208 0u, // uint32_t pushConstantRangeCount;
209 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
210 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
211 });
212 }
213 if (features.geometryShader)
214 {
215 shaderCreateInfos.push_back({
216 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
217 DE_NULL, // const void* pNext;
218 vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT, // VkShaderCreateFlagsEXT flags;
219 vk::VK_SHADER_STAGE_GEOMETRY_BIT, // VkShaderStageFlagBits stage;
220 getNextStage(vk::VK_SHADER_STAGE_GEOMETRY_BIT, features.tessellationShader,
221 features.geometryShader), // VkShaderStageFlags nextStage;
222 vk::VK_SHADER_CODE_TYPE_SPIRV_EXT, // VkShaderCodeTypeEXT codeType;
223 geom.getSize(), // size_t codeSize;
224 geom.getBinary(), // const void* pCode;
225 "main", // const char* pName;
226 0u, // uint32_t setLayoutCount;
227 DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
228 0u, // uint32_t pushConstantRangeCount;
229 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
230 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
231 });
232 }
233 std::vector<vk::VkShaderEXT> shaders(shaderCreateInfos.size());
234 vk.createShadersEXT(device, (uint32_t)shaderCreateInfos.size(), &shaderCreateInfos[0], DE_NULL, &shaders[0]);
235
236 for (uint32_t i = 0; i < (uint32_t)shaderCreateInfos.size(); ++i)
237 {
238 if (shaderCreateInfos[i].stage == stage)
239 {
240 shader = shaders[i];
241 }
242 else
243 {
244 vk.destroyShaderEXT(device, shaders[i], DE_NULL);
245 }
246 }
247 }
248
249 return vk::Move<vk::VkShaderEXT>(vk::check<vk::VkShaderEXT>(shader),
250 vk::Deleter<vk::VkShaderEXT>(vk, device, DE_NULL));
251 }
252
253 class ShaderObjectBinaryQueryInstance : public vkt::TestInstance
254 {
255 public:
ShaderObjectBinaryQueryInstance(Context & context,const TestParams params)256 ShaderObjectBinaryQueryInstance(Context &context, const TestParams params)
257 : vkt::TestInstance(context)
258 , m_params(params)
259 {
260 }
~ShaderObjectBinaryQueryInstance(void)261 virtual ~ShaderObjectBinaryQueryInstance(void)
262 {
263 }
264
265 tcu::TestStatus iterate(void) override;
266
267 private:
268 TestParams m_params;
269 };
270
iterate(void)271 tcu::TestStatus ShaderObjectBinaryQueryInstance::iterate(void)
272 {
273 const auto &vkp = m_context.getPlatformInterface();
274 const vk::VkInstance instance = m_context.getInstance();
275 const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
276 const vk::VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
277 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
278 const vk::VkDevice device = m_context.getDevice();
279 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
280 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
281 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
282
283 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
284 vk::DescriptorSetLayoutBuilder()
285 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
286 .build(vk, device));
287
288 vk::VkDescriptorSetLayout layout =
289 (m_params.stage == vk::VK_SHADER_STAGE_COMPUTE_BIT) ? *descriptorSetLayout : VK_NULL_HANDLE;
290
291 const auto &binaries = m_context.getBinaryCollection();
292 vk::Move<vk::VkShaderEXT> shader =
293 createShader(vk, binaries, device, m_context.getDeviceFeatures(), layout, m_params.linked, m_params.stage);
294
295 size_t dataSize = 0;
296 vk.getShaderBinaryDataEXT(device, *shader, &dataSize, DE_NULL);
297 std::vector<uint8_t> data(dataSize);
298 vk.getShaderBinaryDataEXT(device, *shader, &dataSize, data.data());
299
300 for (uint32_t i = 0; i < 10; ++i)
301 {
302 size_t otherDataSize = 0;
303 std::vector<uint8_t> otherData;
304 if (m_params.queryType == SAME_SHADER)
305 {
306 vk.getShaderBinaryDataEXT(device, *shader, &otherDataSize, DE_NULL);
307 otherData.resize(otherDataSize);
308 vk.getShaderBinaryDataEXT(device, *shader, &otherDataSize, otherData.data());
309 }
310 else if (m_params.queryType == NEW_SHADER)
311 {
312 vk::Move<vk::VkShaderEXT> otherShader = createShader(vk, binaries, device, m_context.getDeviceFeatures(),
313 layout, m_params.linked, m_params.stage);
314 vk.getShaderBinaryDataEXT(device, *otherShader, &otherDataSize, DE_NULL);
315 otherData.resize(otherDataSize);
316 vk.getShaderBinaryDataEXT(device, *otherShader, &otherDataSize, otherData.data());
317 }
318 else if (m_params.queryType == SHADER_FROM_BINARY)
319 {
320 vk::Move<vk::VkShaderEXT> otherShader = vk::createShaderFromBinary(
321 vk, device, m_params.stage, dataSize, data.data(), tessellationSupported, geometrySupported, layout);
322 vk.getShaderBinaryDataEXT(device, *otherShader, &otherDataSize, DE_NULL);
323 otherData.resize(otherDataSize);
324 vk.getShaderBinaryDataEXT(device, *otherShader, &otherDataSize, otherData.data());
325 }
326 else if (m_params.queryType == NEW_DEVICE || m_params.queryType == DEVICE_NO_EXTS_FEATURES)
327 {
328 vk::VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = vk::initVulkanStructure();
329 shaderObjectFeatures.shaderObject = VK_TRUE;
330 vk::VkPhysicalDeviceFeatures2 features2;
331 std::vector<const char *> extensions;
332
333 if (m_params.queryType == DEVICE_NO_EXTS_FEATURES)
334 {
335 features2 = vk::initVulkanStructure(&shaderObjectFeatures);
336 features2.features.tessellationShader = tessellationSupported;
337 features2.features.geometryShader = geometrySupported;
338 extensions.push_back("VK_EXT_shader_object");
339 }
340 else
341 {
342 features2 = m_context.getDeviceFeatures2();
343 extensions = m_context.getDeviceCreationExtensions();
344 }
345 const float queuePriority = 1.0f;
346
347 const vk::VkDeviceQueueCreateInfo deviceQueueCI = {
348 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
349 DE_NULL, // pNext
350 (vk::VkDeviceQueueCreateFlags)0u, // flags
351 queueFamilyIndex, // queueFamilyIndex;
352 1, // queueCount;
353 &queuePriority, // pQueuePriorities;
354 };
355
356 const vk::VkDeviceCreateInfo deviceCreateInfo = {
357 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType;
358 &features2, // pNext;
359 0u, // flags
360 1u, // queueCreateInfoCount;
361 &deviceQueueCI, // pQueueCreateInfos;
362 0u, // layerCount;
363 DE_NULL, // ppEnabledLayerNames;
364 (uint32_t)extensions.size(), // uint32_t enabledExtensionCount;
365 extensions.data(), // const char* const* ppEnabledExtensionNames;
366 DE_NULL, // pEnabledFeatures;
367 };
368
369 vk::Move<vk::VkDevice> otherDevice =
370 createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance,
371 instanceDriver, physicalDevice, &deviceCreateInfo);
372
373 const vk::Unique<vk::VkDescriptorSetLayout> otherDescriptorSetLayout(
374 vk::DescriptorSetLayoutBuilder()
375 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
376 .build(vk, *otherDevice));
377
378 vk::VkDescriptorSetLayout otherLayout =
379 (m_params.stage == vk::VK_SHADER_STAGE_COMPUTE_BIT) ? *otherDescriptorSetLayout : VK_NULL_HANDLE;
380
381 vk::Move<vk::VkShaderEXT> otherShader = createShader(vk, binaries, *otherDevice, features2.features,
382 otherLayout, m_params.linked, m_params.stage);
383 vk.getShaderBinaryDataEXT(*otherDevice, *otherShader, &otherDataSize, DE_NULL);
384 otherData.resize(otherDataSize);
385 vk.getShaderBinaryDataEXT(*otherDevice, *otherShader, &otherDataSize, otherData.data());
386 }
387
388 if (dataSize != otherDataSize)
389 return tcu::TestStatus::fail("Size not matching");
390
391 for (uint32_t j = 0; j < dataSize; ++j)
392 if (data[j] != otherData[j])
393 return tcu::TestStatus::fail("Data not matching");
394 }
395
396 return tcu::TestStatus::pass("Pass");
397 }
398
399 class ShaderObjectBinaryQueryCase : public vkt::TestCase
400 {
401 public:
ShaderObjectBinaryQueryCase(tcu::TestContext & testCtx,const std::string & name,TestParams params)402 ShaderObjectBinaryQueryCase(tcu::TestContext &testCtx, const std::string &name, TestParams params)
403 : vkt::TestCase(testCtx, name)
404 , m_params(params)
405 {
406 }
~ShaderObjectBinaryQueryCase(void)407 virtual ~ShaderObjectBinaryQueryCase(void)
408 {
409 }
410
411 void checkSupport(vkt::Context &context) const override;
412 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const413 TestInstance *createInstance(Context &context) const override
414 {
415 return new ShaderObjectBinaryQueryInstance(context, m_params);
416 }
417
418 private:
419 TestParams m_params;
420 };
421
checkSupport(Context & context) const422 void ShaderObjectBinaryQueryCase::checkSupport(Context &context) const
423 {
424 context.requireDeviceFunctionality("VK_EXT_shader_object");
425
426 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
427 m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
428 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
429 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
430 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
431 }
432
initPrograms(vk::SourceCollections & programCollection) const433 void ShaderObjectBinaryQueryCase::initPrograms(vk::SourceCollections &programCollection) const
434 {
435 vk::addBasicShaderObjectShaders(programCollection);
436 }
437
438 class ShaderObjectIncompatibleBinaryInstance : public vkt::TestInstance
439 {
440 public:
ShaderObjectIncompatibleBinaryInstance(Context & context,vk::VkShaderStageFlagBits shaderStage,const IncompleteBinaryTestType testType)441 ShaderObjectIncompatibleBinaryInstance(Context &context, vk::VkShaderStageFlagBits shaderStage,
442 const IncompleteBinaryTestType testType)
443 : vkt::TestInstance(context)
444 , m_shaderStage(shaderStage)
445 , m_testType(testType)
446 {
447 }
~ShaderObjectIncompatibleBinaryInstance(void)448 virtual ~ShaderObjectIncompatibleBinaryInstance(void)
449 {
450 }
451
452 tcu::TestStatus iterate(void) override;
453
454 private:
455 const vk::VkShaderStageFlagBits m_shaderStage;
456 const IncompleteBinaryTestType m_testType;
457 };
458
iterate(void)459 tcu::TestStatus ShaderObjectIncompatibleBinaryInstance::iterate(void)
460 {
461 const vk::VkInstance instance = m_context.getInstance();
462 const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
463 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
464 const vk::VkDevice device = m_context.getDevice();
465 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
466 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
467
468 const auto &binaries = m_context.getBinaryCollection();
469
470 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
471 vk::DescriptorSetLayoutBuilder()
472 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
473 .build(vk, device));
474
475 vk::VkDescriptorSetLayout layout =
476 (m_shaderStage == vk::VK_SHADER_STAGE_COMPUTE_BIT) ? *descriptorSetLayout : VK_NULL_HANDLE;
477
478 const auto &src = binaries.get(getShaderName(m_shaderStage));
479 const vk::VkShaderCreateInfoEXT shaderCreateInfo = {
480 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
481 DE_NULL, // const void* pNext;
482 0u, // VkShaderCreateFlagsEXT flags;
483 m_shaderStage, // VkShaderStageFlagBits stage;
484 vk::getShaderObjectNextStages(m_shaderStage, tessellationSupported,
485 geometrySupported), // VkShaderStageFlags nextStage;
486 vk::VK_SHADER_CODE_TYPE_SPIRV_EXT, // VkShaderCodeTypeEXT codeType;
487 src.getSize(), // size_t codeSize;
488 src.getBinary(), // const void* pCode;
489 "main", // const char* pName;
490 (layout != VK_NULL_HANDLE) ? 1u : 0u, // uint32_t setLayoutCount;
491 (layout != VK_NULL_HANDLE) ? &layout : DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
492 0u, // uint32_t pushConstantRangeCount;
493 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
494 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
495 };
496
497 vk::Move<vk::VkShaderEXT> shader = vk::createShader(vk, device, shaderCreateInfo);
498 size_t dataSize = 0;
499 vk.getShaderBinaryDataEXT(device, *shader, &dataSize, DE_NULL);
500 std::vector<uint8_t> data(dataSize, 123);
501
502 if (m_testType == HALF_DATA_SIZE)
503 {
504 dataSize /= 2;
505 vk::VkResult result = vk.getShaderBinaryDataEXT(device, *shader, &dataSize, data.data());
506
507 if (result != vk::VK_INCOMPLETE)
508 return tcu::TestStatus::fail("Result was not VK_INCOMPLETE");
509
510 for (const auto &byte : data)
511 if (byte != 123)
512 return tcu::TestStatus::fail("Data was modified");
513
514 if (dataSize != 0)
515 return tcu::TestStatus::fail("Data size was not 0");
516 }
517 else
518 {
519 de::Random random(102030);
520 // Generate random garbage data
521 if (m_testType != CREATE_FROM_HALF_SIZE)
522 {
523 uint32_t i = m_testType == GARBAGE_DATA ? 0u : (uint32_t)dataSize / 2u;
524 for (; i < dataSize; ++i)
525 data[i] = random.getUint8();
526 }
527
528 if (m_testType == CREATE_FROM_HALF_SIZE || m_testType == CREATE_FROM_HALF_SIZE_GARBAGE)
529 dataSize /= 2;
530
531 const vk::VkShaderCreateInfoEXT invalidShaderCreateInfo = {
532 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType;
533 DE_NULL, // const void* pNext;
534 0u, // VkShaderCreateFlagsEXT flags;
535 m_shaderStage, // VkShaderStageFlagBits stage;
536 vk::getShaderObjectNextStages(m_shaderStage, tessellationSupported,
537 geometrySupported), // VkShaderStageFlags nextStage;
538 vk::VK_SHADER_CODE_TYPE_BINARY_EXT, // VkShaderCodeTypeEXT codeType;
539 dataSize, // size_t codeSize;
540 data.data(), // const void* pCode;
541 "main", // const char* pName;
542 (layout != VK_NULL_HANDLE) ? 1u : 0u, // uint32_t setLayoutCount;
543 (layout != VK_NULL_HANDLE) ? &layout : DE_NULL, // VkDescriptorSetLayout* pSetLayouts;
544 0u, // uint32_t pushConstantRangeCount;
545 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
546 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
547 };
548
549 vk::VkShaderEXT dstShader;
550 vk::VkResult result = vk.createShadersEXT(device, 1u, &invalidShaderCreateInfo, DE_NULL, &dstShader);
551
552 if (result != vk::VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT)
553 return tcu::TestStatus::fail("Fail");
554 }
555
556 return tcu::TestStatus::pass("Pass");
557 }
558
559 class ShaderObjectIncompatibleBinaryCase : public vkt::TestCase
560 {
561 public:
ShaderObjectIncompatibleBinaryCase(tcu::TestContext & testCtx,const std::string & name,const vk::VkShaderStageFlagBits shaderStage,const IncompleteBinaryTestType testType)562 ShaderObjectIncompatibleBinaryCase(tcu::TestContext &testCtx, const std::string &name,
563 const vk::VkShaderStageFlagBits shaderStage,
564 const IncompleteBinaryTestType testType)
565 : vkt::TestCase(testCtx, name)
566 , m_shaderStage(shaderStage)
567 , m_testType(testType)
568 {
569 }
~ShaderObjectIncompatibleBinaryCase(void)570 virtual ~ShaderObjectIncompatibleBinaryCase(void)
571 {
572 }
573
574 void checkSupport(vkt::Context &context) const override;
575 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const576 TestInstance *createInstance(Context &context) const override
577 {
578 return new ShaderObjectIncompatibleBinaryInstance(context, m_shaderStage, m_testType);
579 }
580
581 private:
582 const vk::VkShaderStageFlagBits m_shaderStage;
583 const IncompleteBinaryTestType m_testType;
584 };
585
checkSupport(Context & context) const586 void ShaderObjectIncompatibleBinaryCase::checkSupport(Context &context) const
587 {
588 context.requireDeviceFunctionality("VK_EXT_shader_object");
589
590 if (m_shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
591 m_shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
592 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
593 if (m_shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
594 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
595 }
596
initPrograms(vk::SourceCollections & programCollection) const597 void ShaderObjectIncompatibleBinaryCase::initPrograms(vk::SourceCollections &programCollection) const
598 {
599 vk::addBasicShaderObjectShaders(programCollection);
600 }
601
602 class ShaderObjectDeviceFeaturesBinaryInstance : public vkt::TestInstance
603 {
604 public:
ShaderObjectDeviceFeaturesBinaryInstance(Context & context,const bool linked,const vk::VkShaderStageFlagBits stage,const uint32_t index)605 ShaderObjectDeviceFeaturesBinaryInstance(Context &context, const bool linked, const vk::VkShaderStageFlagBits stage,
606 const uint32_t index)
607 : vkt::TestInstance(context)
608 , m_linked(linked)
609 , m_stage(stage)
610 , m_index(index)
611 {
612 }
~ShaderObjectDeviceFeaturesBinaryInstance(void)613 virtual ~ShaderObjectDeviceFeaturesBinaryInstance(void)
614 {
615 }
616
617 tcu::TestStatus iterate(void) override;
618
619 private:
620 const bool m_linked;
621 const vk::VkShaderStageFlagBits m_stage;
622 const uint32_t m_index;
623 };
624
findPNext(const void * pNext,vk::VkStructureType sType)625 const void *findPNext(const void *pNext, vk::VkStructureType sType)
626 {
627 while (pNext != DE_NULL)
628 {
629 if (((vk::VkBaseOutStructure *)pNext)->sType == sType)
630 return (const void *)pNext;
631 pNext = ((vk::VkBaseOutStructure *)pNext)->pNext;
632 }
633 return (const void *)DE_NULL;
634 }
635
iterate(void)636 tcu::TestStatus ShaderObjectDeviceFeaturesBinaryInstance::iterate(void)
637 {
638 const auto &vkp = m_context.getPlatformInterface();
639 const vk::VkInstance instance = m_context.getInstance();
640 const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
641 const vk::VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
642 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
643 const vk::VkDevice device = m_context.getDevice();
644 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
645 const auto &binaries = m_context.getBinaryCollection();
646
647 const vk::VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures();
648
649 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
650 vk::DescriptorSetLayoutBuilder()
651 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
652 .build(vk, device));
653
654 vk::VkDescriptorSetLayout layout =
655 (m_stage == vk::VK_SHADER_STAGE_COMPUTE_BIT) ? *descriptorSetLayout : VK_NULL_HANDLE;
656
657 vk::Move<vk::VkShaderEXT> shader = createShader(vk, binaries, device, features, layout, m_linked, m_stage);
658
659 size_t dataSize = 0;
660 vk.getShaderBinaryDataEXT(device, *shader, &dataSize, DE_NULL);
661 std::vector<uint8_t> data(dataSize);
662 vk.getShaderBinaryDataEXT(device, *shader, &dataSize, data.data());
663
664 size_t otherDataSize = 0;
665 std::vector<uint8_t> otherData;
666
667 const vk::VkPhysicalDeviceFeatures2 features2 = m_context.getDeviceFeatures2();
668 vk::VkPhysicalDeviceFeatures2 testFeatures = m_context.getDeviceFeatures2();
669 std::vector<const char *> extensions = m_context.getDeviceCreationExtensions();
670
671 auto shaderObjectFeatures = m_context.getShaderObjectFeaturesEXT();
672 auto vulkan11features = m_context.getDeviceVulkan11Features();
673 auto vulkan12features = m_context.getDeviceVulkan12Features();
674 auto vulkan13features = m_context.getDeviceVulkan13Features();
675 auto transformFeedbackFeatures = m_context.getTransformFeedbackFeaturesEXT();
676 auto dynamicRenderingFeatures = m_context.getDynamicRenderingFeatures();
677 auto cornerSampledImageFeatures = m_context.getCornerSampledImageFeatures();
678 auto multiviewFeatures = m_context.getMultiviewFeatures();
679 auto shaderDrawParametersFeatures = m_context.getShaderDrawParametersFeatures();
680 auto textureCompressionAstrHdrFeatures = m_context.getTextureCompressionASTCHDRFeatures();
681 auto pipelineRobustnessFeatures = m_context.getPipelineRobustnessFeaturesEXT();
682 auto conditionalRenderingFeatures = m_context.getConditionalRenderingFeaturesEXT();
683 auto shaderFloat16Int8Features = m_context.getShaderFloat16Int8Features();
684 auto f16BitStorageFeatures = m_context.get16BitStorageFeatures();
685 auto depthCilpEnableFeatures = m_context.getDepthClipEnableFeaturesEXT();
686 auto imagelessFramebufferFeatures = m_context.getImagelessFramebufferFeatures();
687 auto performanceQueryFeatures = m_context.getPerformanceQueryFeatures();
688 auto variablePointersFeatures = m_context.getVariablePointersFeatures();
689 auto inlineUniformBlockFeatures = m_context.getInlineUniformBlockFeatures();
690 auto protectedMemoryFeatures = m_context.getProtectedMemoryFeatures();
691 auto blendOperationAdvancedFeatures = m_context.getBlendOperationAdvancedFeaturesEXT();
692 auto accelerationStructureFeatures = m_context.getAccelerationStructureFeatures();
693 auto smBuiltinFeatures = m_context.getShaderSMBuiltinsFeatures();
694 auto samplerYcbcrConversionFeatures = m_context.getSamplerYcbcrConversionFeatures();
695 auto descriptorIndexingFeatures = m_context.getDescriptorIndexingFeatures();
696 auto portabilitySubsetFeatures = m_context.getPortabilitySubsetFeatures();
697 auto shadingRateImageFeatures = m_context.getShadingRateImageFeatures();
698 auto representativeFragmentTestFeatures = m_context.getRepresentativeFragmentTestFeatures();
699 auto shaderSubgroupExtnededTypesFeatures = m_context.getShaderSubgroupExtendedTypesFeatures();
700 auto f8BitStorageFeatures = m_context.get8BitStorageFeatures();
701 auto shaderAtomicInt64Features = m_context.getShaderAtomicInt64Features();
702 auto shaderClockFeatures = m_context.getShaderClockFeatures();
703 auto vertexAttributeDivisorFeatures = m_context.getVertexAttributeDivisorFeatures();
704 auto computeShaderDerivativesFeatures = m_context.getComputeShaderDerivativesFeatures();
705 auto meshShaderFeatures = m_context.getMeshShaderFeaturesEXT();
706 auto fragmentShaderBarycentricFeatures = m_context.getFragmentShaderBarycentricFeatures();
707 auto shaderImageFootprintFeatures = m_context.getShaderImageFootprintFeatures();
708 auto exclusiveScissorFeatures = m_context.getExclusiveScissorFeatures();
709 auto timelineSemaphoreFeatures = m_context.getTimelineSemaphoreFeatures();
710 auto shaderIntegerFunctions2Features = m_context.getShaderIntegerFunctions2FeaturesINTEL();
711 auto vulkanMemoryModelFeatures = m_context.getVulkanMemoryModelFeatures();
712 auto shaderTerminateInvocationFeatures = m_context.getShaderTerminateInvocationFeatures();
713 auto fragmentDensityMapFeatures = m_context.getFragmentDensityMapFeaturesEXT();
714 auto scalarBlockLayoutFeatures = m_context.getScalarBlockLayoutFeatures();
715 auto subgroupSizeControlFeatures = m_context.getSubgroupSizeControlFeatures();
716 auto coherentMemoryFeatures = m_context.getCoherentMemoryFeaturesAMD();
717 auto shaderImageAtomicInt64Features = m_context.getShaderImageAtomicInt64FeaturesEXT();
718 auto memoryPriorityFeatures = m_context.getMemoryPriorityFeaturesEXT();
719 auto dedicatedAllocationImageAliasingFeatures = m_context.getDedicatedAllocationImageAliasingFeatures();
720 auto separateDepthStencilLayoutFeatures = m_context.getSeparateDepthStencilLayoutsFeatures();
721 auto bufferDeviceAddressFeatures = m_context.getBufferDeviceAddressFeatures();
722 auto presentWaitFeatures = m_context.getPresentWaitFeatures();
723 auto cooperativeMatrixFeatures = m_context.getCooperativeMatrixFeatures();
724 auto coverageReductionModeFeatures = m_context.getCoverageReductionModeFeatures();
725 auto fragmentShaderInterlockFeatures = m_context.getFragmentShaderInterlockFeaturesEXT();
726 auto ycbcrImageArraysFeatures = m_context.getYcbcrImageArraysFeaturesEXT();
727 auto uniformBufferStandardLayoutFeatures = m_context.getUniformBufferStandardLayoutFeatures();
728 auto provokingVertexFeatures = m_context.getProvokingVertexFeaturesEXT();
729 auto lineRasterizationFeatures = m_context.getLineRasterizationFeatures();
730 auto shaderAtomicFloatFeatures = m_context.getShaderAtomicFloatFeaturesEXT();
731 auto hostQueryResetFeatures = m_context.getHostQueryResetFeatures();
732 auto indexTypeUint8Features = m_context.getIndexTypeUint8Features();
733 auto extendedDynamicStateFeatures = m_context.getExtendedDynamicStateFeaturesEXT();
734 auto pipelineExecutablePropertiesFeatures = m_context.getPipelineExecutablePropertiesFeatures();
735 auto shaderAtomicFloat2Features = m_context.getShaderAtomicFloat2FeaturesEXT();
736 auto swapchainMaitenance1Features = m_context.getSwapchainMaintenance1FeaturesEXT();
737 auto shaderDemoteToHelperInvocationFeatures = m_context.getShaderDemoteToHelperInvocationFeatures();
738 auto deviceGeneratedCommandsFeatures = m_context.getDeviceGeneratedCommandsFeatures();
739 auto inheritedViewportScissorFeatures = m_context.getInheritedViewportScissorFeatures();
740 auto shaderIntegerDotProductFeatures = m_context.getShaderIntegerDotProductFeatures();
741 auto texelBufferAlignmentFeatures = m_context.getTexelBufferAlignmentFeaturesEXT();
742 auto deviceMemoryReportFeatures = m_context.getDeviceMemoryReportFeaturesEXT();
743 auto robustness2Features = m_context.getRobustness2FeaturesEXT();
744 auto customBorderColorFeatures = m_context.getCustomBorderColorFeaturesEXT();
745 auto presentBarrierFeatures = m_context.getPresentBarrierFeatures();
746 auto presentIdFeatures = m_context.getPresentIdFeatures();
747 auto privateDataFeatures = m_context.getPrivateDataFeatures();
748 auto pipelineCreationCacheControlFeatures = m_context.getPipelineCreationCacheControlFeatures();
749 auto diagnosticConfigFeatures = m_context.getDiagnosticsConfigFeatures();
750 auto synchronization2Features = m_context.getSynchronization2Features();
751 auto descriptorBufferFeatures = m_context.getDescriptorBufferFeaturesEXT();
752 auto graphicsPipelineLibraryFeatures = m_context.getGraphicsPipelineLibraryFeaturesEXT();
753 auto shaderEarlyAndLateFragmentTestsFeatures = m_context.getShaderEarlyAndLateFragmentTestsFeaturesAMD();
754 auto shaderSubgroupUniformControlFlowFeatures = m_context.getShaderSubgroupUniformControlFlowFeatures();
755 auto zeroInitializeWorkgroupMemoryFeatures = m_context.getZeroInitializeWorkgroupMemoryFeatures();
756 auto fragmentShadingRateEnumsFeatures = m_context.getFragmentShadingRateEnumsFeatures();
757 auto rayTracingMotionBlurFeatures = m_context.getRayTracingMotionBlurFeatures();
758 auto ycbcr2Plane444FormatsFeatures = m_context.getYcbcr2Plane444FormatsFeaturesEXT();
759 auto fragmentDensityMap2Features = m_context.getFragmentDensityMap2FeaturesEXT();
760 auto imageRobustnessFeatures = m_context.getImageRobustnessFeatures();
761 auto workgroupMemoryExplicitLayoutFeatures = m_context.getWorkgroupMemoryExplicitLayoutFeatures();
762 auto ImageCompressionControlFeatures = m_context.getImageCompressionControlFeaturesEXT();
763 auto attachmentFeedbackLoopFeatures = m_context.getAttachmentFeedbackLoopLayoutFeaturesEXT();
764 auto f4444FormatsFeatures = m_context.get4444FormatsFeaturesEXT();
765 auto faultFeatures = m_context.getFaultFeaturesEXT();
766 auto rasterizationOrderAttachmentAccessFeatures = m_context.getRasterizationOrderAttachmentAccessFeaturesEXT();
767 auto rgba10x6FormatsFeatures = m_context.getRGBA10X6FormatsFeaturesEXT();
768 auto rayTracingPipelineFeatures = m_context.getRayTracingPipelineFeatures();
769 auto rayQueryFeatures = m_context.getRayQueryFeatures();
770 auto mutableDescriptorTypeFeatures = m_context.getMutableDescriptorTypeFeaturesEXT();
771 auto vertexInputDynamicStateFeatures = m_context.getVertexInputDynamicStateFeaturesEXT();
772 auto addressBindingReportFeatures = m_context.getAddressBindingReportFeaturesEXT();
773 auto depthClipControlFeatures = m_context.getDepthClipControlFeaturesEXT();
774 auto primitiveTopologyListRestartFeatures = m_context.getPrimitiveTopologyListRestartFeaturesEXT();
775 auto subpassShadingFeatures = m_context.getSubpassShadingFeaturesHUAWEI();
776 auto invocationMaskFeatures = m_context.getInvocationMaskFeaturesHUAWEI();
777 auto externalMemoryRDMAFeatures = m_context.getExternalMemoryRDMAFeatures();
778 auto pipelinePropertiesFeatures = m_context.getPipelinePropertiesFeaturesEXT();
779 auto multisampledRenderToSingleSampledFeatures = m_context.getMultisampledRenderToSingleSampledFeaturesEXT();
780 auto extendedDynamicState2Features = m_context.getExtendedDynamicState2FeaturesEXT();
781 auto colorWriteEnableFeatures = m_context.getColorWriteEnableFeaturesEXT();
782 auto primitivesGeneratedQueryFeatures = m_context.getPrimitivesGeneratedQueryFeaturesEXT();
783 auto rayTracingMaintenance1Features = m_context.getRayTracingMaintenance1Features();
784 auto globalPriorityQueryFeatures = m_context.getGlobalPriorityQueryFeatures();
785 auto imageViewMinLodFeatures = m_context.getImageViewMinLodFeaturesEXT();
786 auto multiDrawFeatures = m_context.getMultiDrawFeaturesEXT();
787 auto image2DViewOf3DFeatures = m_context.getImage2DViewOf3DFeaturesEXT();
788 auto opacityMicromapFeatures = m_context.getOpacityMicromapFeaturesEXT();
789 auto displacementMicromapFeatures = m_context.getDisplacementMicromapFeatures();
790 auto clusterCullingShaderFeatures = m_context.getClusterCullingShaderFeaturesHUAWEI();
791 auto borderColorSwizzleFeatures = m_context.getBorderColorSwizzleFeaturesEXT();
792 auto pageableDeviceLocalMemoryFeatures = m_context.getPageableDeviceLocalMemoryFeaturesEXT();
793 auto maintenance4Features = m_context.getMaintenance4Features();
794 auto imageSlicedViewOf3DFeatures = m_context.getImageSlicedViewOf3DFeaturesEXT();
795 auto descriptorSetHostMappingFeatures = m_context.getDescriptorSetHostMappingFeaturesVALVE();
796 auto depthClampZeroOneFeatures = m_context.getDepthClampZeroOneFeaturesEXT();
797 auto nonSeamlessCubeMapFeatures = m_context.getNonSeamlessCubeMapFeaturesEXT();
798 auto fragmentDensityMapOffsetFeatures = m_context.getFragmentDensityMapOffsetFeaturesQCOM();
799 auto copyMemoryIndirectFeatures = m_context.getCopyMemoryIndirectFeatures();
800 auto memoryDecompressionFeatures = m_context.getMemoryDecompressionFeatures();
801 auto linearColorAttachmentFeatures = m_context.getLinearColorAttachmentFeatures();
802 auto imageCompressionControlFeatures = m_context.getImageCompressionControlFeaturesEXT();
803 auto imageCompressionControLSwapchainFeatures = m_context.getImageCompressionControlSwapchainFeaturesEXT();
804 auto imageProcessingFeatures = m_context.getImageProcessingFeaturesQCOM();
805 auto extendedDynamicState3Features = m_context.getExtendedDynamicState3FeaturesEXT();
806 auto subpassMergeFeedbackFeatures = m_context.getSubpassMergeFeedbackFeaturesEXT();
807 auto shaderModuleIdentifierFeatures = m_context.getShaderModuleIdentifierFeaturesEXT();
808 auto opticalFlowFeatures = m_context.getOpticalFlowFeatures();
809 auto legacyDitheringFeatures = m_context.getLegacyDitheringFeaturesEXT();
810 auto pipelineProtectedAccessFeatures = m_context.getPipelineProtectedAccessFeaturesEXT();
811 auto tilePropertiesFeatures = m_context.getTilePropertiesFeaturesQCOM();
812 auto multivewPerViewViewportsFeatures = m_context.getMultiviewPerViewViewportsFeaturesQCOM();
813 auto rayTracingInvocationReorderFeatures = m_context.getRayTracingInvocationReorderFeatures();
814 auto shaderCoreBuiltinsFeatures = m_context.getShaderCoreBuiltinsFeaturesARM();
815 auto pipelineLibraryGroupHandlesFeatures = m_context.getPipelineLibraryGroupHandlesFeaturesEXT();
816 auto multivewPerViewRenderAreasFeatures = m_context.getMultiviewPerViewRenderAreasFeaturesQCOM();
817
818 // These features depend on other features being enabled
819 meshShaderFeatures.multiviewMeshShader = VK_FALSE;
820 meshShaderFeatures.primitiveFragmentShadingRateMeshShader = VK_FALSE;
821
822 std::vector<void *> pNextFeatures = {
823 &vulkan11features,
824 &vulkan12features,
825 &vulkan13features,
826 &transformFeedbackFeatures,
827 &dynamicRenderingFeatures,
828 &cornerSampledImageFeatures,
829 &multiviewFeatures,
830 &shaderDrawParametersFeatures,
831 &textureCompressionAstrHdrFeatures,
832 &pipelineRobustnessFeatures,
833 &conditionalRenderingFeatures,
834 &shaderFloat16Int8Features,
835 &f16BitStorageFeatures,
836 &depthCilpEnableFeatures,
837 &imagelessFramebufferFeatures,
838 &performanceQueryFeatures,
839 &variablePointersFeatures,
840 &inlineUniformBlockFeatures,
841 &protectedMemoryFeatures,
842 &blendOperationAdvancedFeatures,
843 &accelerationStructureFeatures,
844 &smBuiltinFeatures,
845 &samplerYcbcrConversionFeatures,
846 &descriptorIndexingFeatures,
847 &portabilitySubsetFeatures,
848 &shadingRateImageFeatures,
849 &representativeFragmentTestFeatures,
850 &shaderSubgroupExtnededTypesFeatures,
851 &f8BitStorageFeatures,
852 &shaderAtomicInt64Features,
853 &shaderClockFeatures,
854 &vertexAttributeDivisorFeatures,
855 &computeShaderDerivativesFeatures,
856 &meshShaderFeatures,
857 &fragmentShaderBarycentricFeatures,
858 &shaderImageFootprintFeatures,
859 &exclusiveScissorFeatures,
860 &timelineSemaphoreFeatures,
861 &shaderIntegerFunctions2Features,
862 &vulkanMemoryModelFeatures,
863 &shaderTerminateInvocationFeatures,
864 &fragmentDensityMapFeatures,
865 &scalarBlockLayoutFeatures,
866 &subgroupSizeControlFeatures,
867 &coherentMemoryFeatures,
868 &shaderImageAtomicInt64Features,
869 &memoryPriorityFeatures,
870 &dedicatedAllocationImageAliasingFeatures,
871 &separateDepthStencilLayoutFeatures,
872 &bufferDeviceAddressFeatures,
873 &presentWaitFeatures,
874 &cooperativeMatrixFeatures,
875 &coverageReductionModeFeatures,
876 &fragmentShaderInterlockFeatures,
877 &ycbcrImageArraysFeatures,
878 &uniformBufferStandardLayoutFeatures,
879 &provokingVertexFeatures,
880 &lineRasterizationFeatures,
881 &shaderAtomicFloatFeatures,
882 &hostQueryResetFeatures,
883 &indexTypeUint8Features,
884 &extendedDynamicStateFeatures,
885 &pipelineExecutablePropertiesFeatures,
886 &shaderAtomicFloat2Features,
887 &swapchainMaitenance1Features,
888 &shaderDemoteToHelperInvocationFeatures,
889 &deviceGeneratedCommandsFeatures,
890 &inheritedViewportScissorFeatures,
891 &shaderIntegerDotProductFeatures,
892 &texelBufferAlignmentFeatures,
893 &deviceMemoryReportFeatures,
894 &robustness2Features,
895 &customBorderColorFeatures,
896 &presentBarrierFeatures,
897 &presentIdFeatures,
898 &privateDataFeatures,
899 &pipelineCreationCacheControlFeatures,
900 &diagnosticConfigFeatures,
901 &synchronization2Features,
902 &descriptorBufferFeatures,
903 &graphicsPipelineLibraryFeatures,
904 &shaderEarlyAndLateFragmentTestsFeatures,
905 &shaderSubgroupUniformControlFlowFeatures,
906 &zeroInitializeWorkgroupMemoryFeatures,
907 &fragmentShadingRateEnumsFeatures,
908 &rayTracingMotionBlurFeatures,
909 &ycbcr2Plane444FormatsFeatures,
910 &fragmentDensityMap2Features,
911 &imageRobustnessFeatures,
912 &workgroupMemoryExplicitLayoutFeatures,
913 &ImageCompressionControlFeatures,
914 &attachmentFeedbackLoopFeatures,
915 &f4444FormatsFeatures,
916 &faultFeatures,
917 &rasterizationOrderAttachmentAccessFeatures,
918 &rgba10x6FormatsFeatures,
919 &rayTracingPipelineFeatures,
920 &rayQueryFeatures,
921 &mutableDescriptorTypeFeatures,
922 &vertexInputDynamicStateFeatures,
923 &addressBindingReportFeatures,
924 &depthClipControlFeatures,
925 &primitiveTopologyListRestartFeatures,
926 &subpassShadingFeatures,
927 &invocationMaskFeatures,
928 &externalMemoryRDMAFeatures,
929 &pipelinePropertiesFeatures,
930 &multisampledRenderToSingleSampledFeatures,
931 &extendedDynamicState2Features,
932 &colorWriteEnableFeatures,
933 &primitivesGeneratedQueryFeatures,
934 &rayTracingMaintenance1Features,
935 &globalPriorityQueryFeatures,
936 &imageViewMinLodFeatures,
937 &multiDrawFeatures,
938 &image2DViewOf3DFeatures,
939 &opacityMicromapFeatures,
940 &displacementMicromapFeatures,
941 &clusterCullingShaderFeatures,
942 &borderColorSwizzleFeatures,
943 &pageableDeviceLocalMemoryFeatures,
944 &maintenance4Features,
945 &imageSlicedViewOf3DFeatures,
946 &descriptorSetHostMappingFeatures,
947 &depthClampZeroOneFeatures,
948 &nonSeamlessCubeMapFeatures,
949 &fragmentDensityMapOffsetFeatures,
950 ©MemoryIndirectFeatures,
951 &memoryDecompressionFeatures,
952 &linearColorAttachmentFeatures,
953 &imageCompressionControlFeatures,
954 &imageCompressionControLSwapchainFeatures,
955 &imageProcessingFeatures,
956 &extendedDynamicState3Features,
957 &subpassMergeFeedbackFeatures,
958 &shaderModuleIdentifierFeatures,
959 &opticalFlowFeatures,
960 &legacyDitheringFeatures,
961 &pipelineProtectedAccessFeatures,
962 &tilePropertiesFeatures,
963 &multivewPerViewViewportsFeatures,
964 &rayTracingInvocationReorderFeatures,
965 &shaderCoreBuiltinsFeatures,
966 &pipelineLibraryGroupHandlesFeatures,
967 &multivewPerViewRenderAreasFeatures,
968 };
969
970 const float queuePriority = 1.0f;
971
972 const vk::VkDeviceQueueCreateInfo deviceQueueCI = {
973 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
974 DE_NULL, // pNext
975 (vk::VkDeviceQueueCreateFlags)0u, // flags
976 queueFamilyIndex, // queueFamilyIndex;
977 1, // queueCount;
978 &queuePriority, // pQueuePriorities;
979 };
980
981 const vk::VkDeviceCreateInfo deviceCreateInfo = {
982 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType;
983 &testFeatures, // pNext;
984 0u, // flags
985 1u, // queueCreateInfoCount;
986 &deviceQueueCI, // pQueueCreateInfos;
987 0u, // layerCount;
988 DE_NULL, // ppEnabledLayerNames;
989 (uint32_t)extensions.size(), // uint32_t enabledExtensionCount;
990 extensions.data(), // const char* const* ppEnabledExtensionNames;
991 DE_NULL, // pEnabledFeatures;
992 };
993
994 const uint32_t coreFeaturesCount = 50u;
995 const uint32_t pNextFeaturesCount = (uint32_t)pNextFeatures.size();
996
997 // There are too many features to test every combination, so we group them by step = 10
998 const uint32_t step1 = 10u;
999 const uint32_t step2 = 30u;
1000 const uint32_t count2 = uint32_t(std::pow(2u, pNextFeaturesCount / step2));
1001 vk::VkBool32 *coreFeaturesPtr = &testFeatures.features.robustBufferAccess;
1002
1003 for (uint32_t i = 0; i < count2; ++i)
1004 {
1005 // Reset features
1006 testFeatures.features = features2.features;
1007 void *pNext = DE_NULL;
1008 for (uint32_t j = 0; j < coreFeaturesCount; ++j)
1009 {
1010 if (((m_index >> (j / step1)) & 1) == 0)
1011 coreFeaturesPtr[j] = VK_FALSE;
1012 }
1013 for (uint32_t j = 0; j < pNextFeaturesCount; ++j)
1014 {
1015 if (((i >> (j / step2)) & 1) == 1)
1016 {
1017 if (findPNext(features2.pNext, ((vk::VkBaseOutStructure *)pNextFeatures[j])->sType))
1018 {
1019 ((vk::VkBaseOutStructure *)pNextFeatures[j])->pNext = (vk::VkBaseOutStructure *)pNext;
1020 pNext = pNextFeatures[j];
1021 }
1022 }
1023 }
1024
1025 shaderObjectFeatures.pNext = pNext;
1026 testFeatures.pNext = &shaderObjectFeatures;
1027 // Geometry and tessellation features must not be modified
1028 testFeatures.features.tessellationShader = features.tessellationShader;
1029 testFeatures.features.geometryShader = features.geometryShader;
1030
1031 vk::Move<vk::VkDevice> otherDevice =
1032 createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance,
1033 instanceDriver, physicalDevice, &deviceCreateInfo);
1034
1035 const vk::Unique<vk::VkDescriptorSetLayout> otherDescriptorSetLayout(
1036 vk::DescriptorSetLayoutBuilder()
1037 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
1038 .build(vk, *otherDevice));
1039
1040 vk::VkDescriptorSetLayout otherLayout =
1041 (m_stage == vk::VK_SHADER_STAGE_COMPUTE_BIT) ? *otherDescriptorSetLayout : VK_NULL_HANDLE;
1042
1043 vk::Move<vk::VkShaderEXT> otherShader =
1044 createShader(vk, binaries, *otherDevice, features, otherLayout, m_linked, m_stage);
1045 vk.getShaderBinaryDataEXT(*otherDevice, *otherShader, &otherDataSize, DE_NULL);
1046 otherData.resize(otherDataSize);
1047 vk.getShaderBinaryDataEXT(*otherDevice, *otherShader, &otherDataSize, otherData.data());
1048
1049 if (dataSize != otherDataSize)
1050 return tcu::TestStatus::fail("Size not matching");
1051
1052 for (uint32_t j = 0; j < dataSize; ++j)
1053 if (data[j] != otherData[j])
1054 return tcu::TestStatus::fail("Data not matching");
1055 }
1056
1057 return tcu::TestStatus::pass("Pass");
1058 }
1059
1060 class ShaderObjectDeviceFeaturesBinaryCase : public vkt::TestCase
1061 {
1062 public:
ShaderObjectDeviceFeaturesBinaryCase(tcu::TestContext & testCtx,const std::string & name,const bool linked,const vk::VkShaderStageFlagBits stage,const uint32_t index)1063 ShaderObjectDeviceFeaturesBinaryCase(tcu::TestContext &testCtx, const std::string &name, const bool linked,
1064 const vk::VkShaderStageFlagBits stage, const uint32_t index)
1065 : vkt::TestCase(testCtx, name)
1066 , m_linked(linked)
1067 , m_stage(stage)
1068 , m_index(index)
1069 {
1070 }
~ShaderObjectDeviceFeaturesBinaryCase(void)1071 virtual ~ShaderObjectDeviceFeaturesBinaryCase(void)
1072 {
1073 }
1074
1075 void checkSupport(vkt::Context &context) const override;
1076 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const1077 TestInstance *createInstance(Context &context) const override
1078 {
1079 return new ShaderObjectDeviceFeaturesBinaryInstance(context, m_linked, m_stage, m_index);
1080 }
1081
1082 private:
1083 const bool m_linked;
1084 const vk::VkShaderStageFlagBits m_stage;
1085 const uint32_t m_index;
1086 };
1087
checkSupport(Context & context) const1088 void ShaderObjectDeviceFeaturesBinaryCase::checkSupport(Context &context) const
1089 {
1090 context.requireDeviceFunctionality("VK_EXT_shader_object");
1091
1092 if (m_stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
1093 m_stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1094 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
1095 if (m_stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
1096 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
1097 }
1098
initPrograms(vk::SourceCollections & programCollection) const1099 void ShaderObjectDeviceFeaturesBinaryCase::initPrograms(vk::SourceCollections &programCollection) const
1100 {
1101 vk::addBasicShaderObjectShaders(programCollection);
1102 }
1103
getName(QueryType queryType)1104 std::string getName(QueryType queryType)
1105 {
1106 switch (queryType)
1107 {
1108 case SAME_SHADER:
1109 return "same_shader";
1110 break;
1111 case NEW_SHADER:
1112 return "new_shader";
1113 break;
1114 case SHADER_FROM_BINARY:
1115 return "shader_from_binary";
1116 break;
1117 case NEW_DEVICE:
1118 return "new_device";
1119 case DEVICE_NO_EXTS_FEATURES:
1120 return "device_no_exts_features";
1121 default:
1122 DE_ASSERT(0);
1123 break;
1124 }
1125 return {};
1126 }
1127
1128 } // namespace
1129
createShaderObjectBinaryTests(tcu::TestContext & testCtx)1130 tcu::TestCaseGroup *createShaderObjectBinaryTests(tcu::TestContext &testCtx)
1131 {
1132 de::MovePtr<tcu::TestCaseGroup> binaryGroup(new tcu::TestCaseGroup(testCtx, "binary"));
1133
1134 const struct
1135 {
1136 vk::VkShaderStageFlagBits stage;
1137 const char *name;
1138 } stageTests[] = {
1139 {vk::VK_SHADER_STAGE_VERTEX_BIT, "vert"},
1140 {vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc"},
1141 {vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese"},
1142 {vk::VK_SHADER_STAGE_GEOMETRY_BIT, "geom"},
1143 {vk::VK_SHADER_STAGE_FRAGMENT_BIT, "frag"},
1144 {vk::VK_SHADER_STAGE_COMPUTE_BIT, "comp"},
1145 };
1146
1147 const bool linkedTests[] = {
1148 false,
1149 true,
1150 };
1151
1152 const QueryType queryTypeTests[] = {
1153 SAME_SHADER, NEW_SHADER, SHADER_FROM_BINARY, NEW_DEVICE, DEVICE_NO_EXTS_FEATURES,
1154 };
1155
1156 de::MovePtr<tcu::TestCaseGroup> queryGroup(new tcu::TestCaseGroup(testCtx, "query"));
1157 for (const auto &stage : stageTests)
1158 {
1159 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, stage.name));
1160 for (const auto &linked : linkedTests)
1161 {
1162 if (linked && stage.stage == vk::VK_SHADER_STAGE_COMPUTE_BIT)
1163 continue;
1164
1165 std::string linkedName = linked ? "linked" : "unlinked";
1166 de::MovePtr<tcu::TestCaseGroup> linkedGroup(new tcu::TestCaseGroup(testCtx, linkedName.c_str()));
1167 for (const auto &queryType : queryTypeTests)
1168 {
1169 TestParams params = {
1170 stage.stage,
1171 linked,
1172 queryType,
1173 };
1174 linkedGroup->addChild(new ShaderObjectBinaryQueryCase(testCtx, getName(queryType), params));
1175 }
1176 stageGroup->addChild(linkedGroup.release());
1177 }
1178 queryGroup->addChild(stageGroup.release());
1179 }
1180
1181 const struct
1182 {
1183 IncompleteBinaryTestType type;
1184 const char *name;
1185 } incompatibleTests[] = {
1186 {
1187 HALF_DATA_SIZE,
1188 "half_size",
1189 },
1190 {
1191 GARBAGE_DATA,
1192 "garbage_data",
1193 },
1194 {
1195 GARBAGE_SECOND_HALF,
1196 "garbage_second_half",
1197 },
1198 {CREATE_FROM_HALF_SIZE, "create_from_half_size"},
1199 {CREATE_FROM_HALF_SIZE_GARBAGE, "create_from_half_size_garbage"},
1200 };
1201
1202 de::MovePtr<tcu::TestCaseGroup> incompatibleGroup(new tcu::TestCaseGroup(testCtx, "incompatible"));
1203 for (const auto &stage : stageTests)
1204 {
1205 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, stage.name));
1206 for (const auto &testType : incompatibleTests)
1207 {
1208 stageGroup->addChild(
1209 new ShaderObjectIncompatibleBinaryCase(testCtx, testType.name, stage.stage, testType.type));
1210 }
1211 incompatibleGroup->addChild(stageGroup.release());
1212 }
1213
1214 de::MovePtr<tcu::TestCaseGroup> deviceFeaturesGroup(new tcu::TestCaseGroup(testCtx, "device_features"));
1215 for (const auto &stage : stageTests)
1216 {
1217 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, stage.name));
1218 for (const auto &linked : linkedTests)
1219 {
1220 if (linked && stage.stage == vk::VK_SHADER_STAGE_COMPUTE_BIT)
1221 continue;
1222
1223 std::string linkedName = linked ? "linked" : "unlinked";
1224 de::MovePtr<tcu::TestCaseGroup> linkedGroup(new tcu::TestCaseGroup(testCtx, linkedName.c_str()));
1225 for (uint32_t i = 0; i < 32; ++i)
1226 {
1227 linkedGroup->addChild(
1228 new ShaderObjectDeviceFeaturesBinaryCase(testCtx, std::to_string(i), linked, stage.stage, i));
1229 }
1230 stageGroup->addChild(linkedGroup.release());
1231 }
1232 deviceFeaturesGroup->addChild(stageGroup.release());
1233 }
1234
1235 binaryGroup->addChild(queryGroup.release());
1236 binaryGroup->addChild(incompatibleGroup.release());
1237 binaryGroup->addChild(deviceFeaturesGroup.release());
1238
1239 return binaryGroup.release();
1240 }
1241
1242 } // namespace ShaderObject
1243 } // namespace vkt
1244