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