1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2017 The Khronos Group Inc. 6 * Copyright (c) 2018 NVIDIA Corporation 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 Vulkan descriptor set tests 23 *//*--------------------------------------------------------------------*/ 24 25 // These tests generate random descriptor set layouts, where each descriptor 26 // set has a random number of bindings, each binding has a random array size 27 // and random descriptor type. The descriptor types are all backed by buffers 28 // or buffer views, and each buffer is filled with a unique integer starting 29 // from zero. The shader fetches from each descriptor (possibly using dynamic 30 // indexing of the descriptor array) and compares against the expected value. 31 // 32 // The different test cases vary the maximum number of descriptors used of 33 // each type. "Low" limit tests use the spec minimum maximum limit, "high" 34 // limit tests use up to 4k descriptors of the corresponding type. Test cases 35 // also vary the type indexing used, and shader stage. 36 37 #include "vktBindingDescriptorSetRandomTests.hpp" 38 39 #include "vkBufferWithMemory.hpp" 40 #include "vkImageWithMemory.hpp" 41 #include "vkQueryUtil.hpp" 42 #include "vkBuilderUtil.hpp" 43 #include "vkCmdUtil.hpp" 44 #include "vkTypeUtil.hpp" 45 #include "vktTestGroupUtil.hpp" 46 #include "vktTestCase.hpp" 47 48 #include "deDefs.h" 49 #include "deMath.h" 50 #include "deRandom.h" 51 #include "deSharedPtr.hpp" 52 #include "deString.h" 53 54 #include "tcuTestCase.hpp" 55 #include "tcuTestLog.hpp" 56 57 #include <string> 58 #include <sstream> 59 60 namespace vkt 61 { 62 namespace BindingModel 63 { 64 namespace 65 { 66 using namespace vk; 67 using namespace std; 68 69 static const deUint32 DIM = 8; 70 71 typedef enum 72 { 73 INDEX_TYPE_NONE = 0, 74 INDEX_TYPE_CONSTANT, 75 INDEX_TYPE_PUSHCONSTANT, 76 INDEX_TYPE_DEPENDENT, 77 INDEX_TYPE_RUNTIME_SIZE, 78 } IndexType; 79 80 typedef enum 81 { 82 STAGE_COMPUTE = 0, 83 STAGE_VERTEX, 84 STAGE_FRAGMENT, 85 } Stage; 86 87 typedef enum 88 { 89 UPDATE_AFTER_BIND_DISABLED = 0, 90 UPDATE_AFTER_BIND_ENABLED, 91 } UpdateAfterBind; 92 93 const VkFlags allShaderStages = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; 94 const VkFlags allPipelineStages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; 95 96 struct CaseDef 97 { 98 IndexType indexType; 99 deUint32 numDescriptorSets; 100 deUint32 maxPerStageUniformBuffers; 101 deUint32 maxUniformBuffersDynamic; 102 deUint32 maxPerStageStorageBuffers; 103 deUint32 maxStorageBuffersDynamic; 104 deUint32 maxPerStageSampledImages; 105 deUint32 maxPerStageStorageImages; 106 deUint32 maxInlineUniformBlocks; 107 deUint32 maxInlineUniformBlockSize; 108 Stage stage; 109 UpdateAfterBind uab; 110 deUint32 seed; 111 }; 112 113 114 class RandomLayout 115 { 116 public: 117 RandomLayout(deUint32 numSets) : 118 layoutBindings(numSets), 119 layoutBindingFlags(numSets), 120 arraySizes(numSets), 121 variableDescriptorSizes(numSets) 122 { 123 } 124 125 // These three are indexed by [set][binding] 126 vector<vector<VkDescriptorSetLayoutBinding> > layoutBindings; 127 vector<vector<VkDescriptorBindingFlagsEXT> > layoutBindingFlags; 128 vector<vector<deUint32> > arraySizes; 129 // size of the variable descriptor (last) binding in each set 130 vector<deUint32> variableDescriptorSizes; 131 132 }; 133 134 135 class DescriptorSetRandomTestInstance : public TestInstance 136 { 137 public: 138 DescriptorSetRandomTestInstance (Context& context, const CaseDef& data); 139 ~DescriptorSetRandomTestInstance (void); 140 tcu::TestStatus iterate (void); 141 private: 142 CaseDef m_data; 143 144 enum 145 { 146 WIDTH = 256, 147 HEIGHT = 256 148 }; 149 }; 150 151 DescriptorSetRandomTestInstance::DescriptorSetRandomTestInstance (Context& context, const CaseDef& data) 152 : vkt::TestInstance (context) 153 , m_data (data) 154 { 155 } 156 157 DescriptorSetRandomTestInstance::~DescriptorSetRandomTestInstance (void) 158 { 159 } 160 161 class DescriptorSetRandomTestCase : public TestCase 162 { 163 public: 164 DescriptorSetRandomTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data); 165 ~DescriptorSetRandomTestCase (void); 166 virtual void initPrograms (SourceCollections& programCollection) const; 167 virtual TestInstance* createInstance (Context& context) const; 168 virtual void checkSupport (Context& context) const; 169 170 private: 171 CaseDef m_data; 172 }; 173 174 DescriptorSetRandomTestCase::DescriptorSetRandomTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data) 175 : vkt::TestCase (context, name, desc) 176 , m_data (data) 177 { 178 } 179 180 DescriptorSetRandomTestCase::~DescriptorSetRandomTestCase (void) 181 { 182 } 183 184 void DescriptorSetRandomTestCase::checkSupport(Context& context) const 185 { 186 VkPhysicalDeviceInlineUniformBlockPropertiesEXT inlineUniformProperties; 187 deMemset(&inlineUniformProperties, 0, sizeof(inlineUniformProperties)); 188 inlineUniformProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT; 189 190 VkPhysicalDeviceProperties2 properties; 191 deMemset(&properties, 0, sizeof(properties)); 192 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 193 194 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_inline_uniform_block")) 195 { 196 properties.pNext = &inlineUniformProperties; 197 } 198 199 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties); 200 201 VkPhysicalDeviceInlineUniformBlockFeaturesEXT inlineUniformFeatures; 202 deMemset(&inlineUniformFeatures, 0, sizeof(inlineUniformFeatures)); 203 inlineUniformFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT; 204 205 VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures; 206 deMemset(&indexingFeatures, 0, sizeof(indexingFeatures)); 207 indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; 208 209 VkPhysicalDeviceFeatures2 features; 210 deMemset(&features, 0, sizeof(features)); 211 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 212 213 if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_descriptor_indexing") && 214 isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_inline_uniform_block")) 215 { 216 indexingFeatures.pNext = &inlineUniformFeatures; 217 features.pNext = &indexingFeatures; 218 } 219 else if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_descriptor_indexing")) 220 { 221 features.pNext = &indexingFeatures; 222 } 223 else if (isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_inline_uniform_block")) 224 { 225 features.pNext = &inlineUniformFeatures; 226 } 227 228 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features); 229 if (m_data.stage == STAGE_VERTEX && !features.features.vertexPipelineStoresAndAtomics) 230 { 231 return TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported"); 232 } 233 234 if ((m_data.indexType == INDEX_TYPE_PUSHCONSTANT || 235 m_data.indexType == INDEX_TYPE_DEPENDENT || 236 m_data.indexType == INDEX_TYPE_RUNTIME_SIZE) && 237 (!features.features.shaderUniformBufferArrayDynamicIndexing || 238 !features.features.shaderStorageBufferArrayDynamicIndexing || 239 !features.features.shaderSampledImageArrayDynamicIndexing || 240 !features.features.shaderStorageImageArrayDynamicIndexing || 241 !indexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing || 242 !indexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing)) 243 { 244 TCU_THROW(NotSupportedError, "Dynamic indexing not supported"); 245 } 246 247 if (m_data.numDescriptorSets > properties.properties.limits.maxBoundDescriptorSets) 248 { 249 TCU_THROW(NotSupportedError, "Number of descriptor sets not supported"); 250 } 251 252 if ((m_data.maxPerStageUniformBuffers + m_data.maxPerStageStorageBuffers + 253 m_data.maxPerStageSampledImages + m_data.maxPerStageStorageImages) > 254 properties.properties.limits.maxPerStageResources) 255 { 256 TCU_THROW(NotSupportedError, "Number of descriptors not supported"); 257 } 258 259 if (m_data.maxPerStageUniformBuffers > properties.properties.limits.maxPerStageDescriptorUniformBuffers || 260 m_data.maxPerStageStorageBuffers > properties.properties.limits.maxPerStageDescriptorStorageBuffers || 261 m_data.maxUniformBuffersDynamic > properties.properties.limits.maxDescriptorSetUniformBuffersDynamic || 262 m_data.maxStorageBuffersDynamic > properties.properties.limits.maxDescriptorSetStorageBuffersDynamic || 263 m_data.maxPerStageSampledImages > properties.properties.limits.maxPerStageDescriptorSampledImages || 264 m_data.maxPerStageStorageImages > properties.properties.limits.maxPerStageDescriptorStorageImages) 265 { 266 TCU_THROW(NotSupportedError, "Number of descriptors not supported"); 267 } 268 269 if (m_data.maxInlineUniformBlocks != 0 && 270 !inlineUniformFeatures.inlineUniformBlock) 271 { 272 TCU_THROW(NotSupportedError, "Inline uniform blocks not supported"); 273 } 274 275 if (m_data.maxInlineUniformBlocks > inlineUniformProperties.maxPerStageDescriptorInlineUniformBlocks) 276 { 277 TCU_THROW(NotSupportedError, "Number of inline uniform blocks not supported"); 278 } 279 280 if (m_data.maxInlineUniformBlocks != 0 && 281 m_data.maxInlineUniformBlockSize > inlineUniformProperties.maxInlineUniformBlockSize) 282 { 283 TCU_THROW(NotSupportedError, "Inline uniform block size not supported"); 284 } 285 286 if (m_data.indexType == INDEX_TYPE_RUNTIME_SIZE && 287 !indexingFeatures.runtimeDescriptorArray) 288 { 289 TCU_THROW(NotSupportedError, "runtimeDescriptorArray not supported"); 290 } 291 } 292 293 // Return a random value in the range [min, max] 294 deInt32 randRange(deRandom *rnd, deInt32 min, deInt32 max) 295 { 296 if (max < 0) 297 return 0; 298 299 return (deRandom_getUint32(rnd) % (max - min + 1)) + min; 300 } 301 302 void generateRandomLayout(RandomLayout &randomLayout, const CaseDef &caseDef) 303 { 304 deRandom rnd; 305 deRandom_init(&rnd, caseDef.seed); 306 307 // Count the number of each resource type, to avoid overflowing the limits. 308 deUint32 numUBO = 0; 309 deUint32 numUBODyn = 0; 310 deUint32 numSSBO = 0; 311 deUint32 numSSBODyn = 0; 312 deUint32 numImage = 0; 313 deUint32 numTexBuffer = 0; 314 deUint32 numInlineUniformBlocks = 0; 315 316 // TODO: Consider varying these 317 deUint32 minBindings = 0; 318 deUint32 maxBindings = 32; 319 // No larger than 32 elements for dynamic indexing tests, due to 128B limit 320 // for push constants (used for the indices) 321 deUint32 maxArray = caseDef.indexType == INDEX_TYPE_NONE ? 0 : 32; 322 323 // Each set has a random number of bindings, each binding has a random 324 // array size and a random descriptor type. 325 for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s) 326 { 327 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s]; 328 vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s]; 329 vector<deUint32> &arraySizes = randomLayout.arraySizes[s]; 330 int numBindings = randRange(&rnd, minBindings, maxBindings); 331 332 // Guarantee room for the output image 333 if (s == 0 && numBindings == 0) 334 { 335 numBindings = 1; 336 } 337 338 bindings = vector<VkDescriptorSetLayoutBinding>(numBindings); 339 bindingsFlags = vector<VkDescriptorBindingFlagsEXT>(numBindings); 340 arraySizes = vector<deUint32>(numBindings); 341 } 342 343 // BUFFER_DYNAMIC descriptor types cannot be used with VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT bindings in one set 344 bool allowDynamicBuffers = caseDef.uab != UPDATE_AFTER_BIND_ENABLED; 345 346 // Iterate over bindings first, then over sets. This prevents the low-limit bindings 347 // from getting clustered in low-numbered sets. 348 for (deUint32 b = 0; b <= maxBindings; ++b) 349 { 350 for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s) 351 { 352 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s]; 353 vector<deUint32> &arraySizes = randomLayout.arraySizes[s]; 354 355 if (b >= bindings.size()) 356 { 357 continue; 358 } 359 360 VkDescriptorSetLayoutBinding &binding = bindings[b]; 361 binding.binding = b; 362 binding.pImmutableSamplers = NULL; 363 binding.stageFlags = allShaderStages; 364 365 // Output image 366 if (s == 0 && b == 0) 367 { 368 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 369 binding.descriptorCount = 1; 370 numImage++; 371 arraySizes[b] = 0; 372 continue; 373 } 374 375 binding.descriptorCount = 0; 376 377 // Select a random type of descriptor. 378 int r = randRange(&rnd, 0, (allowDynamicBuffers ? 6 : 4)); 379 switch (r) 380 { 381 default: DE_ASSERT(0); // Fallthrough 382 case 0: 383 binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 384 if (numUBO < caseDef.maxPerStageUniformBuffers) 385 { 386 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageUniformBuffers - numUBO)); 387 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1; 388 numUBO += binding.descriptorCount; 389 } 390 break; 391 case 1: 392 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 393 if (numSSBO < caseDef.maxPerStageStorageBuffers) 394 { 395 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageStorageBuffers - numSSBO)); 396 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1; 397 numSSBO += binding.descriptorCount; 398 } 399 break; 400 case 2: 401 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 402 if (numImage < caseDef.maxPerStageStorageImages) 403 { 404 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageStorageImages - numImage)); 405 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1; 406 numImage += binding.descriptorCount; 407 } 408 break; 409 case 3: 410 binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 411 if (numTexBuffer < caseDef.maxPerStageSampledImages) 412 { 413 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, caseDef.maxPerStageSampledImages - numTexBuffer)); 414 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1; 415 numTexBuffer += binding.descriptorCount; 416 } 417 break; 418 case 4: 419 if (caseDef.maxInlineUniformBlocks > 0) 420 { 421 binding.descriptorType = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT; 422 if (numInlineUniformBlocks < caseDef.maxInlineUniformBlocks) 423 { 424 arraySizes[b] = randRange(&rnd, 1, (caseDef.maxInlineUniformBlockSize - 16) / 16); // subtract 16 for "ivec4 dummy" 425 arraySizes[b] = de::min(maxArray, arraySizes[b]); 426 binding.descriptorCount = (arraySizes[b] ? arraySizes[b] : 1) * 16 + 16; // add 16 for "ivec4 dummy" 427 numInlineUniformBlocks++; 428 } 429 } 430 else 431 { 432 // Plug in a dummy descriptor type, so validation layers that don't 433 // support inline_uniform_block don't crash. 434 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 435 } 436 break; 437 case 5: 438 binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 439 if (numUBODyn < caseDef.maxUniformBuffersDynamic && 440 numUBO < caseDef.maxPerStageUniformBuffers) 441 { 442 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, de::min(caseDef.maxUniformBuffersDynamic - numUBODyn, 443 caseDef.maxPerStageUniformBuffers - numUBO))); 444 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1; 445 numUBO += binding.descriptorCount; 446 numUBODyn += binding.descriptorCount; 447 } 448 break; 449 case 6: 450 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 451 if (numSSBODyn < caseDef.maxStorageBuffersDynamic && 452 numSSBO < caseDef.maxPerStageStorageBuffers) 453 { 454 arraySizes[b] = randRange(&rnd, 0, de::min(maxArray, de::min(caseDef.maxStorageBuffersDynamic - numSSBODyn, 455 caseDef.maxPerStageStorageBuffers - numSSBO))); 456 binding.descriptorCount = arraySizes[b] ? arraySizes[b] : 1; 457 numSSBO += binding.descriptorCount; 458 numSSBODyn += binding.descriptorCount; 459 } 460 break; 461 } 462 } 463 } 464 465 for (deUint32 s = 0; s < caseDef.numDescriptorSets; ++s) 466 { 467 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s]; 468 vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s]; 469 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes; 470 471 // Choose a variable descriptor count size. If the feature is not supported, we'll just 472 // allocate the whole thing later on. 473 if (bindings.size() > 0 && 474 bindings[bindings.size()-1].descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC && 475 bindings[bindings.size()-1].descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC && 476 !(s == 0 && bindings.size() == 1) && // Don't cut out the output image binding 477 randRange(&rnd, 1,4) == 1) // 1 in 4 chance 478 { 479 480 bindingsFlags[bindings.size()-1] |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT; 481 variableDescriptorSizes[s] = randRange(&rnd, 0,bindings[bindings.size()-1].descriptorCount); 482 if (bindings[bindings.size()-1].descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) 483 { 484 // keep a multiple of 16B 485 variableDescriptorSizes[s] &= ~0xF; 486 } 487 } 488 } 489 } 490 491 void DescriptorSetRandomTestCase::initPrograms (SourceCollections& programCollection) const 492 { 493 RandomLayout randomLayout(m_data.numDescriptorSets); 494 generateRandomLayout(randomLayout, m_data); 495 496 std::stringstream decls, checks; 497 498 deUint32 descriptor = 0; 499 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s) 500 { 501 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s]; 502 vector<VkDescriptorBindingFlagsEXT> bindingsFlags = randomLayout.layoutBindingFlags[s]; 503 vector<deUint32> &arraySizes = randomLayout.arraySizes[s]; 504 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes; 505 506 for (size_t b = 0; b < bindings.size(); ++b) 507 { 508 VkDescriptorSetLayoutBinding &binding = bindings[b]; 509 deUint32 descriptorIncrement = (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 16 : 1; 510 511 // Construct the declaration for the binding 512 if (binding.descriptorCount > 0) 513 { 514 std::stringstream array; 515 if (m_data.indexType == INDEX_TYPE_RUNTIME_SIZE && 516 binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) 517 { 518 if (arraySizes[b]) 519 { 520 array << "[]"; 521 } 522 } 523 else 524 { 525 if (arraySizes[b]) 526 { 527 array << "[" << arraySizes[b] << "]"; 528 } 529 } 530 switch (binding.descriptorType) 531 { 532 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: 533 decls << "layout(set = " << s << ", binding = " << b << ") uniform inlineubodef" << s << "_" << b << " { ivec4 dummy; int val" << array.str() << "; } inlineubo" << s << "_" << b << ";\n"; 534 break; 535 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 536 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 537 decls << "layout(set = " << s << ", binding = " << b << ") uniform ubodef" << s << "_" << b << " { int val; } ubo" << s << "_" << b << array.str() << ";\n"; 538 break; 539 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 540 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 541 decls << "layout(set = " << s << ", binding = " << b << ") buffer sbodef" << s << "_" << b << " { int val; } ssbo" << s << "_" << b << array.str() << ";\n"; 542 break; 543 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 544 decls << "layout(set = " << s << ", binding = " << b << ") uniform itextureBuffer texbo" << s << "_" << b << array.str() << ";\n"; 545 break; 546 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 547 decls << "layout(r32i, set = " << s << ", binding = " << b << ") uniform iimageBuffer image" << s << "_" << b << array.str() << ";\n"; 548 break; 549 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 550 decls << "layout(r32ui, set = " << s << ", binding = " << b << ") uniform uimage2D image" << s << "_" << b << array.str() << ";\n"; 551 break; 552 default: DE_ASSERT(0); 553 } 554 555 for (deUint32 ai = 0; ai < de::max(1u, arraySizes[b]); ++ai, descriptor += descriptorIncrement) 556 { 557 // Don't access descriptors past the end of the allocated range for 558 // variable descriptor count 559 if (b == bindings.size() - 1 && 560 (bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT)) 561 { 562 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) 563 { 564 // Convert to bytes and add 16 for "ivec4 dummy" in case of inline uniform block 565 const deUint32 uboRange = ai*16 + 16; 566 if (uboRange >= variableDescriptorSizes[s]) 567 continue; 568 } 569 else 570 { 571 if (ai >= variableDescriptorSizes[s]) 572 continue; 573 } 574 } 575 576 if (s == 0 && b == 0) 577 { 578 // This is the output image, skip. 579 continue; 580 } 581 582 // Check that the value in the descriptor equals its descriptor number. 583 // i.e. check "ubo[c].val == descriptor" or "ubo[pushconst[c]].val == descriptor" 584 585 // First, construct the index. This can be a constant literal, a value 586 // from a push constant, or a function of the previous descriptor value. 587 std::stringstream ind; 588 switch (m_data.indexType) 589 { 590 case INDEX_TYPE_NONE: 591 case INDEX_TYPE_CONSTANT: 592 // The index is just the constant literal 593 if (arraySizes[b]) 594 { 595 ind << "[" << ai << "]"; 596 } 597 break; 598 case INDEX_TYPE_PUSHCONSTANT: 599 // identity is an int[], directly index it 600 if (arraySizes[b]) 601 { 602 ind << "[pc.identity[" << ai << "]]"; 603 } 604 break; 605 case INDEX_TYPE_RUNTIME_SIZE: 606 case INDEX_TYPE_DEPENDENT: 607 // Index is a function of the previous return value (which is reset to zero) 608 if (arraySizes[b]) 609 { 610 ind << "[accum + " << ai << "]"; 611 } 612 break; 613 default: DE_ASSERT(0); 614 } 615 616 // For very large bindings, only check every N=201 descriptors (chosen arbitrarily) 617 bool checkDescriptor = true; 618 if (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) 619 { 620 // For "large" bindings, only check every N=3 descriptors (chosen arbitrarily). 621 // This is meant to reduce shader compile time. 622 if (ai > 2 && 623 binding.descriptorCount >= 4 && 624 (ai % 3) != 0) 625 { 626 checkDescriptor = false; 627 } 628 } 629 630 if (checkDescriptor) 631 { 632 // Fetch from the descriptor. 633 switch (binding.descriptorType) 634 { 635 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: 636 checks << " temp = inlineubo" << s << "_" << b << ".val" << ind.str() << ";\n"; 637 break; 638 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 639 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 640 checks << " temp = ubo" << s << "_" << b << ind.str() << ".val;\n"; 641 break; 642 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 643 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 644 checks << " temp = ssbo" << s << "_" << b << ind.str() << ".val;\n"; 645 break; 646 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 647 checks << " temp = texelFetch(texbo" << s << "_" << b << ind.str() << ", 0).x;\n"; 648 break; 649 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 650 checks << " temp = imageLoad(image" << s << "_" << b << ind.str() << ", 0).x;\n"; 651 break; 652 default: DE_ASSERT(0); 653 } 654 if (m_data.indexType == INDEX_TYPE_DEPENDENT || m_data.indexType == INDEX_TYPE_RUNTIME_SIZE) 655 { 656 // Set accum to zero, it is added to the next index. 657 checks << " accum = temp - " << descriptor << ";\n"; 658 } 659 else 660 { 661 // Accumulate any incorrect values. 662 checks << " accum |= temp - " << descriptor << ";\n"; 663 } 664 } 665 } 666 } 667 } 668 } 669 670 std::stringstream pushdecl; 671 switch (m_data.indexType) 672 { 673 case INDEX_TYPE_PUSHCONSTANT: 674 pushdecl << "layout (push_constant, std430) uniform Block { int identity[32]; } pc;\n"; 675 break; 676 default: DE_ASSERT(0); 677 case INDEX_TYPE_NONE: 678 case INDEX_TYPE_CONSTANT: 679 case INDEX_TYPE_DEPENDENT: 680 case INDEX_TYPE_RUNTIME_SIZE: 681 break; 682 } 683 684 685 switch (m_data.stage) 686 { 687 default: DE_ASSERT(0); // Fallthrough 688 case STAGE_COMPUTE: 689 { 690 std::stringstream css; 691 css << 692 "#version 450 core\n" 693 "#extension GL_EXT_nonuniform_qualifier : enable\n" 694 << pushdecl.str() 695 << decls.str() << 696 "layout(local_size_x = 1, local_size_y = 1) in;\n" 697 "void main()\n" 698 "{\n" 699 " int accum = 0, temp;\n" 700 << checks.str() << 701 " uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n" 702 " imageStore(image0_0, ivec2(gl_GlobalInvocationID.xy), color);\n" 703 "}\n"; 704 705 programCollection.glslSources.add("test") << glu::ComputeSource(css.str()); 706 break; 707 } 708 case STAGE_VERTEX: 709 { 710 std::stringstream vss; 711 vss << 712 "#version 450 core\n" 713 "#extension GL_EXT_nonuniform_qualifier : enable\n" 714 << pushdecl.str() 715 << decls.str() << 716 "void main()\n" 717 "{\n" 718 " int accum = 0, temp;\n" 719 << checks.str() << 720 " uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n" 721 " imageStore(image0_0, ivec2(gl_VertexIndex % " << DIM << ", gl_VertexIndex / " << DIM << "), color);\n" 722 " gl_PointSize = 1.0f;\n" 723 " gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n" 724 "}\n"; 725 726 programCollection.glslSources.add("test") << glu::VertexSource(vss.str()); 727 break; 728 } 729 case STAGE_FRAGMENT: 730 { 731 std::stringstream vss; 732 vss << 733 "#version 450 core\n" 734 "void main()\n" 735 "{\n" 736 // full-viewport quad 737 " gl_Position = vec4( 2.0*float(gl_VertexIndex&2) - 1.0, 4.0*(gl_VertexIndex&1)-1.0, 1.0 - 2.0 * float(gl_VertexIndex&1), 1);\n" 738 "}\n"; 739 740 programCollection.glslSources.add("vert") << glu::VertexSource(vss.str()); 741 742 std::stringstream fss; 743 fss << 744 "#version 450 core\n" 745 "#extension GL_EXT_nonuniform_qualifier : enable\n" 746 << pushdecl.str() 747 << decls.str() << 748 "void main()\n" 749 "{\n" 750 " int accum = 0, temp;\n" 751 << checks.str() << 752 " uvec4 color = (accum != 0) ? uvec4(0,0,0,0) : uvec4(1,0,0,1);\n" 753 " imageStore(image0_0, ivec2(gl_FragCoord.x, gl_FragCoord.y), color);\n" 754 "}\n"; 755 756 programCollection.glslSources.add("test") << glu::FragmentSource(fss.str()); 757 break; 758 } 759 } 760 761 } 762 763 TestInstance* DescriptorSetRandomTestCase::createInstance (Context& context) const 764 { 765 return new DescriptorSetRandomTestInstance(context, m_data); 766 } 767 768 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize, 769 const VkBufferUsageFlags usage) 770 { 771 const VkBufferCreateInfo bufferCreateInfo = 772 { 773 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 774 DE_NULL, // const void* pNext; 775 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags; 776 bufferSize, // VkDeviceSize size; 777 usage, // VkBufferUsageFlags usage; 778 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 779 0u, // deUint32 queueFamilyIndexCount; 780 DE_NULL, // const deUint32* pQueueFamilyIndices; 781 }; 782 return bufferCreateInfo; 783 } 784 785 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk, 786 const VkDevice device, 787 const void* pNext, 788 const VkDescriptorPool descriptorPool, 789 const VkDescriptorSetLayout setLayout) 790 { 791 const VkDescriptorSetAllocateInfo allocateParams = 792 { 793 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 794 pNext, // const void* pNext; 795 descriptorPool, // VkDescriptorPool descriptorPool; 796 1u, // deUint32 setLayoutCount; 797 &setLayout, // const VkDescriptorSetLayout* pSetLayouts; 798 }; 799 return allocateDescriptorSet(vk, device, &allocateParams); 800 } 801 802 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent, 803 const VkImageSubresourceLayers subresourceLayers) 804 { 805 const VkBufferImageCopy copyParams = 806 { 807 0ull, // VkDeviceSize bufferOffset; 808 0u, // deUint32 bufferRowLength; 809 0u, // deUint32 bufferImageHeight; 810 subresourceLayers, // VkImageSubresourceLayers imageSubresource; 811 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 812 extent, // VkExtent3D imageExtent; 813 }; 814 return copyParams; 815 } 816 817 tcu::TestStatus DescriptorSetRandomTestInstance::iterate (void) 818 { 819 const DeviceInterface& vk = m_context.getDeviceInterface(); 820 const VkDevice device = m_context.getDevice(); 821 Allocator& allocator = m_context.getDefaultAllocator(); 822 823 RandomLayout randomLayout(m_data.numDescriptorSets); 824 generateRandomLayout(randomLayout, m_data); 825 826 827 VkPhysicalDeviceProperties2 properties; 828 deMemset(&properties, 0, sizeof(properties)); 829 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 830 831 m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties); 832 833 VkPhysicalDeviceInlineUniformBlockFeaturesEXT inlineUniformFeatures; 834 deMemset(&inlineUniformFeatures, 0, sizeof(inlineUniformFeatures)); 835 inlineUniformFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT; 836 837 VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures; 838 deMemset(&indexingFeatures, 0, sizeof(indexingFeatures)); 839 indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; 840 841 VkPhysicalDeviceFeatures2 features; 842 deMemset(&features, 0, sizeof(features)); 843 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 844 845 if (isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_EXT_descriptor_indexing") && 846 isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_EXT_inline_uniform_block")) 847 { 848 indexingFeatures.pNext = &inlineUniformFeatures; 849 features.pNext = &indexingFeatures; 850 } 851 else if (isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_EXT_descriptor_indexing")) 852 { 853 features.pNext = &indexingFeatures; 854 } 855 else if (isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_EXT_inline_uniform_block")) 856 { 857 features.pNext = &inlineUniformFeatures; 858 } 859 860 m_context.getInstanceInterface().getPhysicalDeviceFeatures2(m_context.getPhysicalDevice(), &features); 861 862 deRandom rnd; 863 deRandom_init(&rnd, m_data.seed); 864 865 VkPipelineBindPoint bindPoint = m_data.stage == STAGE_COMPUTE ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS; 866 867 DE_ASSERT(m_data.numDescriptorSets <= 32); 868 Move<vk::VkDescriptorSetLayout> descriptorSetLayouts[32]; 869 Move<vk::VkDescriptorPool> descriptorPools[32]; 870 Move<vk::VkDescriptorSet> descriptorSets[32]; 871 872 deUint32 numDescriptors = 0; 873 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s) 874 { 875 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s]; 876 vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s]; 877 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes; 878 879 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 880 VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0; 881 882 for (size_t b = 0; b < bindings.size(); ++b) 883 { 884 VkDescriptorSetLayoutBinding &binding = bindings[b]; 885 numDescriptors += binding.descriptorCount; 886 887 // Randomly choose some bindings to use update-after-bind, if it is supported 888 if (m_data.uab == UPDATE_AFTER_BIND_ENABLED && 889 randRange(&rnd, 1, 8) == 1 && // 1 in 8 chance 890 (binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || indexingFeatures.descriptorBindingUniformBufferUpdateAfterBind) && 891 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || indexingFeatures.descriptorBindingStorageImageUpdateAfterBind) && 892 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || indexingFeatures.descriptorBindingStorageBufferUpdateAfterBind) && 893 (binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || indexingFeatures.descriptorBindingUniformTexelBufferUpdateAfterBind) && 894 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || indexingFeatures.descriptorBindingStorageTexelBufferUpdateAfterBind) && 895 (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT || inlineUniformFeatures.descriptorBindingInlineUniformBlockUpdateAfterBind) && 896 (binding.descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) && 897 (binding.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) 898 { 899 bindingsFlags[b] |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT; 900 layoutCreateFlags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT; 901 poolCreateFlags |= VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT; 902 } 903 904 if (!indexingFeatures.descriptorBindingVariableDescriptorCount) 905 { 906 bindingsFlags[b] &= ~VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT; 907 } 908 } 909 910 // Create a layout and allocate a descriptor set for it. 911 912 const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT bindingFlagsInfo = 913 { 914 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT, // VkStructureType sType; 915 DE_NULL, // const void* pNext; 916 (deUint32)bindings.size(), // uint32_t bindingCount; 917 bindings.empty() ? DE_NULL : &bindingsFlags[0], // const VkDescriptorBindingFlagsEXT* pBindingFlags; 918 }; 919 920 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo = 921 { 922 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 923 &bindingFlagsInfo, 924 925 layoutCreateFlags, 926 (deUint32)bindings.size(), 927 bindings.empty() ? DE_NULL : &bindings[0] 928 }; 929 930 descriptorSetLayouts[s] = vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo); 931 932 vk::DescriptorPoolBuilder poolBuilder; 933 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, m_data.maxPerStageUniformBuffers); 934 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, m_data.maxUniformBuffersDynamic); 935 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_data.maxPerStageStorageBuffers); 936 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, m_data.maxStorageBuffersDynamic); 937 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, m_data.maxPerStageSampledImages); 938 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, m_data.maxPerStageStorageImages); 939 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1); 940 if (m_data.maxInlineUniformBlocks) 941 { 942 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, m_data.maxInlineUniformBlocks * m_data.maxInlineUniformBlockSize); 943 } 944 945 VkDescriptorPoolInlineUniformBlockCreateInfoEXT inlineUniformBlockPoolCreateInfo = 946 { 947 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT, // VkStructureType sType; 948 DE_NULL, // const void* pNext; 949 m_data.maxInlineUniformBlocks, // uint32_t maxInlineUniformBlockBindings; 950 }; 951 952 descriptorPools[s] = poolBuilder.build(vk, device, poolCreateFlags, 1u, 953 m_data.maxInlineUniformBlocks ? &inlineUniformBlockPoolCreateInfo : DE_NULL); 954 955 VkDescriptorSetVariableDescriptorCountAllocateInfoEXT variableCountInfo = 956 { 957 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT, // VkStructureType sType; 958 DE_NULL, // const void* pNext; 959 0, // uint32_t descriptorSetCount; 960 DE_NULL, // const uint32_t* pDescriptorCounts; 961 }; 962 963 const void *pNext = DE_NULL; 964 if (bindings.size() > 0 && 965 bindingsFlags[bindings.size()-1] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT) 966 { 967 variableCountInfo.descriptorSetCount = 1; 968 variableCountInfo.pDescriptorCounts = &variableDescriptorSizes[s]; 969 pNext = &variableCountInfo; 970 } 971 972 descriptorSets[s] = makeDescriptorSet(vk, device, pNext, *descriptorPools[s], *descriptorSetLayouts[s]); 973 } 974 975 976 VkDeviceSize align = de::max(de::max(de::max(properties.properties.limits.minTexelBufferOffsetAlignment, 977 properties.properties.limits.minUniformBufferOffsetAlignment), 978 properties.properties.limits.minStorageBufferOffsetAlignment), 979 (VkDeviceSize)sizeof(deUint32)); 980 981 de::MovePtr<BufferWithMemory> buffer; 982 buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory( 983 vk, device, allocator, makeBufferCreateInfo(align*numDescriptors, 984 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | 985 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | 986 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | 987 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), 988 MemoryRequirement::HostVisible)); 989 deUint8 *bufferPtr = (deUint8 *)buffer->getAllocation().getHostPtr(); 990 991 typedef vk::Unique<vk::VkBufferView> BufferViewHandleUp; 992 typedef de::SharedPtr<BufferViewHandleUp> BufferViewHandleSp; 993 994 vector<BufferViewHandleSp> bufferViews(de::max(1u,numDescriptors)); 995 996 // Create a buffer and view for each descriptor. Fill descriptor 'd' 997 // with an integer value equal to 'd'. 998 int descriptor = 0; 999 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s) 1000 { 1001 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s]; 1002 for (size_t b = 0; b < bindings.size(); ++b) 1003 { 1004 VkDescriptorSetLayoutBinding &binding = bindings[b]; 1005 1006 if (binding.descriptorCount == 0) 1007 { 1008 continue; 1009 } 1010 if (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) 1011 { 1012 for (deUint32 d = descriptor; d < descriptor + binding.descriptorCount; ++d) 1013 { 1014 deUint32 *ptr = (deUint32 *)(bufferPtr + align*d); 1015 *ptr = d; 1016 1017 const vk::VkBufferViewCreateInfo viewCreateInfo = 1018 { 1019 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, 1020 DE_NULL, 1021 (vk::VkBufferViewCreateFlags)0, 1022 **buffer, // buffer 1023 VK_FORMAT_R32_SINT, // format 1024 (vk::VkDeviceSize)align*d, // offset 1025 (vk::VkDeviceSize)sizeof(deUint32) // range 1026 }; 1027 vk::Move<vk::VkBufferView> bufferView = vk::createBufferView(vk, device, &viewCreateInfo); 1028 bufferViews[d] = BufferViewHandleSp(new BufferViewHandleUp(bufferView)); 1029 } 1030 descriptor += binding.descriptorCount; 1031 } 1032 else 1033 { 1034 // subtract 16 for "ivec4 dummy" 1035 DE_ASSERT(binding.descriptorCount >= 16); 1036 descriptor += binding.descriptorCount - 16; 1037 } 1038 } 1039 } 1040 1041 flushMappedMemoryRange(vk, device, buffer->getAllocation().getMemory(), buffer->getAllocation().getOffset(), VK_WHOLE_SIZE); 1042 1043 const VkQueue queue = m_context.getUniversalQueue(); 1044 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, 0, m_context.getUniversalQueueFamilyIndex()); 1045 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1046 1047 beginCommandBuffer(vk, *cmdBuffer, 0u); 1048 1049 // Push constants are used for dynamic indexing. PushConstant[i] = i. 1050 1051 const VkPushConstantRange pushConstRange = 1052 { 1053 allShaderStages, // VkShaderStageFlags stageFlags 1054 0, // deUint32 offset 1055 128 // deUint32 size 1056 }; 1057 1058 vector<vk::VkDescriptorSetLayout> descriptorSetLayoutsRaw(m_data.numDescriptorSets); 1059 for (size_t i = 0; i < m_data.numDescriptorSets; ++i) 1060 { 1061 descriptorSetLayoutsRaw[i] = descriptorSetLayouts[i].get(); 1062 } 1063 1064 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = 1065 { 1066 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType 1067 DE_NULL, // pNext 1068 (VkPipelineLayoutCreateFlags)0, 1069 m_data.numDescriptorSets, // setLayoutCount 1070 &descriptorSetLayoutsRaw[0], // pSetLayouts 1071 m_data.indexType == INDEX_TYPE_PUSHCONSTANT ? 1u : 0u, // pushConstantRangeCount 1072 &pushConstRange, // pPushConstantRanges 1073 }; 1074 1075 Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL); 1076 1077 if (m_data.indexType == INDEX_TYPE_PUSHCONSTANT) 1078 { 1079 // PushConstant[i] = i 1080 for (deUint32 i = 0; i < (deUint32)(128 / sizeof(deUint32)); ++i) 1081 { 1082 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, allShaderStages, 1083 (deUint32)(i * sizeof(deUint32)), (deUint32)sizeof(deUint32), &i); 1084 } 1085 } 1086 1087 de::MovePtr<BufferWithMemory> copyBuffer; 1088 copyBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory( 1089 vk, device, allocator, makeBufferCreateInfo(DIM*DIM*sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible)); 1090 1091 const VkImageCreateInfo imageCreateInfo = 1092 { 1093 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1094 DE_NULL, // const void* pNext; 1095 (VkImageCreateFlags)0u, // VkImageCreateFlags flags; 1096 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1097 VK_FORMAT_R32_UINT, // VkFormat format; 1098 { 1099 DIM, // deUint32 width; 1100 DIM, // deUint32 height; 1101 1u // deUint32 depth; 1102 }, // VkExtent3D extent; 1103 1u, // deUint32 mipLevels; 1104 1u, // deUint32 arrayLayers; 1105 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1106 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1107 VK_IMAGE_USAGE_STORAGE_BIT 1108 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT 1109 | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 1110 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1111 0u, // deUint32 queueFamilyIndexCount; 1112 DE_NULL, // const deUint32* pQueueFamilyIndices; 1113 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 1114 }; 1115 1116 VkImageViewCreateInfo imageViewCreateInfo = 1117 { 1118 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 1119 DE_NULL, // const void* pNext; 1120 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags; 1121 DE_NULL, // VkImage image; 1122 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 1123 VK_FORMAT_R32_UINT, // VkFormat format; 1124 { 1125 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r; 1126 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g; 1127 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b; 1128 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a; 1129 }, // VkComponentMapping components; 1130 { 1131 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1132 0u, // deUint32 baseMipLevel; 1133 1u, // deUint32 levelCount; 1134 0u, // deUint32 baseArrayLayer; 1135 1u // deUint32 layerCount; 1136 } // VkImageSubresourceRange subresourceRange; 1137 }; 1138 1139 de::MovePtr<ImageWithMemory> image; 1140 Move<VkImageView> imageView; 1141 1142 image = de::MovePtr<ImageWithMemory>(new ImageWithMemory( 1143 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any)); 1144 imageViewCreateInfo.image = **image; 1145 imageView = createImageView(vk, device, &imageViewCreateInfo, NULL); 1146 1147 descriptor = 0; 1148 for (deUint32 s = 0; s < m_data.numDescriptorSets; ++s) 1149 { 1150 vector<VkDescriptorSetLayoutBinding> &bindings = randomLayout.layoutBindings[s]; 1151 vector<VkDescriptorBindingFlagsEXT> &bindingsFlags = randomLayout.layoutBindingFlags[s]; 1152 vector<deUint32> &arraySizes = randomLayout.arraySizes[s]; 1153 vector<deUint32> &variableDescriptorSizes = randomLayout.variableDescriptorSizes; 1154 1155 vector<VkDescriptorBufferInfo> bufferInfoVec(numDescriptors); 1156 vector<VkDescriptorImageInfo> imageInfoVec(numDescriptors); 1157 vector<VkBufferView> bufferViewVec(numDescriptors); 1158 vector<VkWriteDescriptorSetInlineUniformBlockEXT> inlineInfoVec(numDescriptors); 1159 vector<deUint32> descriptorNumber(numDescriptors); 1160 vector<VkWriteDescriptorSet> writesBeforeBindVec(0); 1161 vector<VkWriteDescriptorSet> writesAfterBindVec(0); 1162 int vecIndex = 0; 1163 int numDynamic = 0; 1164 1165 vector<VkDescriptorUpdateTemplateEntry> imgTemplateEntriesBefore, imgTemplateEntriesAfter, 1166 bufTemplateEntriesBefore, bufTemplateEntriesAfter, 1167 texelBufTemplateEntriesBefore, texelBufTemplateEntriesAfter, 1168 inlineTemplateEntriesBefore, inlineTemplateEntriesAfter; 1169 1170 for (size_t b = 0; b < bindings.size(); ++b) 1171 { 1172 VkDescriptorSetLayoutBinding &binding = bindings[b]; 1173 deUint32 descriptorIncrement = (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 16 : 1; 1174 1175 // Construct the declaration for the binding 1176 if (binding.descriptorCount > 0) 1177 { 1178 bool updateAfterBind = !!(bindingsFlags[b] & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT); 1179 for (deUint32 ai = 0; ai < de::max(1u, arraySizes[b]); ++ai, descriptor += descriptorIncrement) 1180 { 1181 // Don't access descriptors past the end of the allocated range for 1182 // variable descriptor count 1183 if (b == bindings.size() - 1 && 1184 (bindingsFlags[b] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT)) 1185 { 1186 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) 1187 { 1188 // Convert to bytes and add 16 for "ivec4 dummy" in case of inline uniform block 1189 const deUint32 uboRange = ai*16 + 16; 1190 if (uboRange >= variableDescriptorSizes[s]) 1191 continue; 1192 } 1193 else 1194 { 1195 if (ai >= variableDescriptorSizes[s]) 1196 continue; 1197 } 1198 } 1199 1200 // output image 1201 imageInfoVec[vecIndex] = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL); 1202 1203 if (binding.descriptorType != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) 1204 { 1205 bufferInfoVec[vecIndex] = makeDescriptorBufferInfo(**buffer, descriptor*align, sizeof(deUint32)); 1206 bufferViewVec[vecIndex] = **bufferViews[descriptor]; 1207 } 1208 1209 descriptorNumber[descriptor] = descriptor; 1210 1211 VkWriteDescriptorSet w = 1212 { 1213 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType 1214 DE_NULL, // pNext 1215 *descriptorSets[s], // dstSet 1216 (deUint32)b, // binding 1217 ai, // dstArrayElement 1218 1u, // descriptorCount 1219 binding.descriptorType, // descriptorType 1220 &imageInfoVec[vecIndex], // pImageInfo 1221 &bufferInfoVec[vecIndex], // pBufferInfo 1222 &bufferViewVec[vecIndex], // pTexelBufferView 1223 }; 1224 1225 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) 1226 { 1227 VkWriteDescriptorSetInlineUniformBlockEXT inlineUniformBlock = 1228 { 1229 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT, // VkStructureType sType; 1230 DE_NULL, // const void* pNext; 1231 sizeof(deUint32), // uint32_t dataSize; 1232 &descriptorNumber[descriptor], // const void* pData; 1233 }; 1234 1235 inlineInfoVec[vecIndex] = inlineUniformBlock; 1236 w.dstArrayElement = ai*16 + 16; // add 16 to skip "ivec4 dummy" 1237 w.pNext = &inlineInfoVec[vecIndex]; 1238 w.descriptorCount = sizeof(deUint32); 1239 } 1240 1241 VkDescriptorUpdateTemplateEntry templateEntry = 1242 { 1243 (deUint32)b, // uint32_t dstBinding; 1244 ai, // uint32_t dstArrayElement; 1245 1u, // uint32_t descriptorCount; 1246 binding.descriptorType, // VkDescriptorType descriptorType; 1247 0, // size_t offset; 1248 0, // size_t stride; 1249 }; 1250 1251 switch (binding.descriptorType) 1252 { 1253 default: DE_ASSERT(0); // Fallthrough 1254 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 1255 templateEntry.offset = vecIndex * sizeof(VkDescriptorImageInfo); 1256 (updateAfterBind ? imgTemplateEntriesAfter : imgTemplateEntriesBefore).push_back(templateEntry); 1257 break; 1258 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 1259 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 1260 templateEntry.offset = vecIndex * sizeof(VkBufferView); 1261 (updateAfterBind ? texelBufTemplateEntriesAfter : texelBufTemplateEntriesBefore).push_back(templateEntry); 1262 break; 1263 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 1264 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1265 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 1266 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 1267 templateEntry.offset = vecIndex * sizeof(VkDescriptorBufferInfo); 1268 (updateAfterBind ? bufTemplateEntriesAfter : bufTemplateEntriesBefore).push_back(templateEntry); 1269 break; 1270 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: 1271 templateEntry.offset = descriptor * sizeof(deUint32); 1272 templateEntry.dstArrayElement = ai*16 + 16; // add 16 to skip "ivec4 dummy" 1273 templateEntry.descriptorCount = sizeof(deUint32); 1274 (updateAfterBind ? inlineTemplateEntriesAfter : inlineTemplateEntriesBefore).push_back(templateEntry); 1275 break; 1276 } 1277 1278 vecIndex++; 1279 1280 (updateAfterBind ? writesAfterBindVec : writesBeforeBindVec).push_back(w); 1281 1282 // Count the number of dynamic descriptors in this set. 1283 if (binding.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 1284 binding.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) 1285 { 1286 numDynamic++; 1287 } 1288 } 1289 } 1290 } 1291 1292 // Make zeros have at least one element so &zeros[0] works 1293 vector<deUint32> zeros(de::max(1,numDynamic)); 1294 deMemset(&zeros[0], 0, numDynamic * sizeof(deUint32)); 1295 1296 // Randomly select between vkUpdateDescriptorSets and vkUpdateDescriptorSetWithTemplate 1297 if (randRange(&rnd, 1, 2) == 1 && 1298 m_context.contextSupports(vk::ApiVersion(1, 1, 0))) 1299 { 1300 VkDescriptorUpdateTemplateCreateInfo templateCreateInfo = 1301 { 1302 VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, // VkStructureType sType; 1303 NULL, // void* pNext; 1304 0, // VkDescriptorUpdateTemplateCreateFlags flags; 1305 0, // uint32_t descriptorUpdateEntryCount; 1306 DE_NULL, // uint32_t descriptorUpdateEntryCount; 1307 VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, // VkDescriptorUpdateTemplateType templateType; 1308 descriptorSetLayouts[s].get(), // VkDescriptorSetLayout descriptorSetLayout; 1309 bindPoint, // VkPipelineBindPoint pipelineBindPoint; 1310 0, // VkPipelineLayout pipelineLayout; 1311 0, // uint32_t set; 1312 }; 1313 1314 void *templateVectorData[] = 1315 { 1316 &imageInfoVec[0], 1317 &bufferInfoVec[0], 1318 &bufferViewVec[0], 1319 &descriptorNumber[0], 1320 }; 1321 1322 vector<VkDescriptorUpdateTemplateEntry> *templateVectorsBefore[] = 1323 { 1324 &imgTemplateEntriesBefore, 1325 &bufTemplateEntriesBefore, 1326 &texelBufTemplateEntriesBefore, 1327 &inlineTemplateEntriesBefore, 1328 }; 1329 1330 vector<VkDescriptorUpdateTemplateEntry> *templateVectorsAfter[] = 1331 { 1332 &imgTemplateEntriesAfter, 1333 &bufTemplateEntriesAfter, 1334 &texelBufTemplateEntriesAfter, 1335 &inlineTemplateEntriesAfter, 1336 }; 1337 1338 for (size_t i = 0; i < sizeof(templateVectorsBefore) / sizeof(templateVectorsBefore[0]); ++i) 1339 { 1340 if (templateVectorsBefore[i]->size()) 1341 { 1342 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)templateVectorsBefore[i]->size(); 1343 templateCreateInfo.pDescriptorUpdateEntries = &((*templateVectorsBefore[i])[0]); 1344 Move<VkDescriptorUpdateTemplate> descriptorUpdateTemplate = createDescriptorUpdateTemplate(vk, device, &templateCreateInfo, NULL); 1345 vk.updateDescriptorSetWithTemplate(device, descriptorSets[s].get(), *descriptorUpdateTemplate, templateVectorData[i]); 1346 } 1347 } 1348 1349 vk.cmdBindDescriptorSets(*cmdBuffer, bindPoint, *pipelineLayout, s, 1, &descriptorSets[s].get(), numDynamic, &zeros[0]); 1350 1351 for (size_t i = 0; i < sizeof(templateVectorsAfter) / sizeof(templateVectorsAfter[0]); ++i) 1352 { 1353 if (templateVectorsAfter[i]->size()) 1354 { 1355 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)templateVectorsAfter[i]->size(); 1356 templateCreateInfo.pDescriptorUpdateEntries = &((*templateVectorsAfter[i])[0]); 1357 Move<VkDescriptorUpdateTemplate> descriptorUpdateTemplate = createDescriptorUpdateTemplate(vk, device, &templateCreateInfo, NULL); 1358 vk.updateDescriptorSetWithTemplate(device, descriptorSets[s].get(), *descriptorUpdateTemplate, templateVectorData[i]); 1359 } 1360 } 1361 1362 } 1363 else 1364 { 1365 if (writesBeforeBindVec.size()) 1366 { 1367 vk.updateDescriptorSets(device, (deUint32)writesBeforeBindVec.size(), &writesBeforeBindVec[0], 0, NULL); 1368 } 1369 1370 vk.cmdBindDescriptorSets(*cmdBuffer, bindPoint, *pipelineLayout, s, 1, &descriptorSets[s].get(), numDynamic, &zeros[0]); 1371 1372 if (writesAfterBindVec.size()) 1373 { 1374 vk.updateDescriptorSets(device, (deUint32)writesAfterBindVec.size(), &writesAfterBindVec[0], 0, NULL); 1375 } 1376 } 1377 } 1378 1379 Move<VkPipeline> pipeline; 1380 Move<VkRenderPass> renderPass; 1381 Move<VkFramebuffer> framebuffer; 1382 1383 if (m_data.stage == STAGE_COMPUTE) 1384 { 1385 const Unique<VkShaderModule> shader(createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0)); 1386 1387 const VkPipelineShaderStageCreateInfo shaderCreateInfo = 1388 { 1389 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1390 DE_NULL, 1391 (VkPipelineShaderStageCreateFlags)0, 1392 VK_SHADER_STAGE_COMPUTE_BIT, // stage 1393 *shader, // shader 1394 "main", 1395 DE_NULL, // pSpecializationInfo 1396 }; 1397 1398 const VkComputePipelineCreateInfo pipelineCreateInfo = 1399 { 1400 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 1401 DE_NULL, 1402 0u, // flags 1403 shaderCreateInfo, // cs 1404 *pipelineLayout, // layout 1405 (vk::VkPipeline)0, // basePipelineHandle 1406 0u, // basePipelineIndex 1407 }; 1408 pipeline = createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo, NULL); 1409 } 1410 else 1411 { 1412 1413 const vk::VkSubpassDescription subpassDesc = 1414 { 1415 (vk::VkSubpassDescriptionFlags)0, 1416 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint 1417 0u, // inputCount 1418 DE_NULL, // pInputAttachments 1419 0u, // colorCount 1420 DE_NULL, // pColorAttachments 1421 DE_NULL, // pResolveAttachments 1422 DE_NULL, // depthStencilAttachment 1423 0u, // preserveCount 1424 DE_NULL, // pPreserveAttachments 1425 }; 1426 const vk::VkRenderPassCreateInfo renderPassParams = 1427 { 1428 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType 1429 DE_NULL, // pNext 1430 (vk::VkRenderPassCreateFlags)0, 1431 0u, // attachmentCount 1432 DE_NULL, // pAttachments 1433 1u, // subpassCount 1434 &subpassDesc, // pSubpasses 1435 0u, // dependencyCount 1436 DE_NULL, // pDependencies 1437 }; 1438 1439 renderPass = createRenderPass(vk, device, &renderPassParams); 1440 1441 const vk::VkFramebufferCreateInfo framebufferParams = 1442 { 1443 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType 1444 DE_NULL, // pNext 1445 (vk::VkFramebufferCreateFlags)0, 1446 *renderPass, // renderPass 1447 0u, // attachmentCount 1448 DE_NULL, // pAttachments 1449 DIM, // width 1450 DIM, // height 1451 1u, // layers 1452 }; 1453 1454 framebuffer = createFramebuffer(vk, device, &framebufferParams); 1455 1456 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = 1457 { 1458 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1459 DE_NULL, // const void* pNext; 1460 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 1461 0u, // deUint32 vertexBindingDescriptionCount; 1462 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1463 0u, // deUint32 vertexAttributeDescriptionCount; 1464 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1465 }; 1466 1467 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = 1468 { 1469 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 1470 DE_NULL, // const void* pNext; 1471 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 1472 (m_data.stage == STAGE_VERTEX) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology; 1473 VK_FALSE // VkBool32 primitiveRestartEnable; 1474 }; 1475 1476 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = 1477 { 1478 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 1479 DE_NULL, // const void* pNext; 1480 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 1481 VK_FALSE, // VkBool32 depthClampEnable; 1482 (m_data.stage == STAGE_VERTEX) ? VK_TRUE : VK_FALSE, // VkBool32 rasterizerDiscardEnable; 1483 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 1484 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 1485 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace; 1486 VK_FALSE, // VkBool32 depthBiasEnable; 1487 0.0f, // float depthBiasConstantFactor; 1488 0.0f, // float depthBiasClamp; 1489 0.0f, // float depthBiasSlopeFactor; 1490 1.0f // float lineWidth; 1491 }; 1492 1493 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = 1494 { 1495 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType 1496 DE_NULL, // const void* pNext 1497 0u, // VkPipelineMultisampleStateCreateFlags flags 1498 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples 1499 VK_FALSE, // VkBool32 sampleShadingEnable 1500 1.0f, // float minSampleShading 1501 DE_NULL, // const VkSampleMask* pSampleMask 1502 VK_FALSE, // VkBool32 alphaToCoverageEnable 1503 VK_FALSE // VkBool32 alphaToOneEnable 1504 }; 1505 1506 VkViewport viewport = makeViewport(DIM, DIM); 1507 VkRect2D scissor = makeRect2D(DIM, DIM); 1508 1509 const VkPipelineViewportStateCreateInfo viewportStateCreateInfo = 1510 { 1511 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType 1512 DE_NULL, // const void* pNext 1513 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags 1514 1u, // deUint32 viewportCount 1515 &viewport, // const VkViewport* pViewports 1516 1u, // deUint32 scissorCount 1517 &scissor // const VkRect2D* pScissors 1518 }; 1519 1520 Move<VkShaderModule> fs; 1521 Move<VkShaderModule> vs; 1522 1523 deUint32 numStages; 1524 if (m_data.stage == STAGE_VERTEX) 1525 { 1526 vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0); 1527 fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0); // bogus 1528 numStages = 1u; 1529 } 1530 else 1531 { 1532 vs = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0); 1533 fs = createShaderModule(vk, device, m_context.getBinaryCollection().get("test"), 0); 1534 numStages = 2u; 1535 } 1536 1537 const VkPipelineShaderStageCreateInfo shaderCreateInfo[2] = 1538 { 1539 { 1540 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1541 DE_NULL, 1542 (VkPipelineShaderStageCreateFlags)0, 1543 VK_SHADER_STAGE_VERTEX_BIT, // stage 1544 *vs, // shader 1545 "main", 1546 DE_NULL, // pSpecializationInfo 1547 }, 1548 { 1549 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1550 DE_NULL, 1551 (VkPipelineShaderStageCreateFlags)0, 1552 VK_SHADER_STAGE_FRAGMENT_BIT, // stage 1553 *fs, // shader 1554 "main", 1555 DE_NULL, // pSpecializationInfo 1556 } 1557 }; 1558 1559 const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = 1560 { 1561 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1562 DE_NULL, // const void* pNext; 1563 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 1564 numStages, // deUint32 stageCount; 1565 &shaderCreateInfo[0], // const VkPipelineShaderStageCreateInfo* pStages; 1566 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1567 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1568 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1569 &viewportStateCreateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; 1570 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 1571 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1572 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1573 DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1574 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1575 pipelineLayout.get(), // VkPipelineLayout layout; 1576 renderPass.get(), // VkRenderPass renderPass; 1577 0u, // deUint32 subpass; 1578 DE_NULL, // VkPipeline basePipelineHandle; 1579 0 // int basePipelineIndex; 1580 }; 1581 1582 pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo); 1583 } 1584 1585 const VkImageMemoryBarrier imageBarrier = 1586 { 1587 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType 1588 DE_NULL, // const void* pNext 1589 0u, // VkAccessFlags srcAccessMask 1590 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask 1591 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout 1592 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout 1593 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex 1594 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex 1595 **image, // VkImage image 1596 { 1597 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask 1598 0u, // uint32_t baseMipLevel 1599 1u, // uint32_t mipLevels, 1600 0u, // uint32_t baseArray 1601 1u, // uint32_t arraySize 1602 } 1603 }; 1604 1605 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 1606 (VkDependencyFlags)0, 1607 0, (const VkMemoryBarrier*)DE_NULL, 1608 0, (const VkBufferMemoryBarrier*)DE_NULL, 1609 1, &imageBarrier); 1610 1611 vk.cmdBindPipeline(*cmdBuffer, bindPoint, *pipeline); 1612 1613 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 1614 VkClearValue clearColor = makeClearValueColorU32(0,0,0,0); 1615 1616 VkMemoryBarrier memBarrier = 1617 { 1618 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType 1619 DE_NULL, // pNext 1620 0u, // srcAccessMask 1621 0u, // dstAccessMask 1622 }; 1623 1624 vk.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range); 1625 1626 memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 1627 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; 1628 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, allPipelineStages, 1629 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL); 1630 1631 if (m_data.stage == STAGE_COMPUTE) 1632 { 1633 vk.cmdDispatch(*cmdBuffer, DIM, DIM, 1); 1634 } 1635 else 1636 { 1637 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, 1638 makeRect2D(DIM, DIM), 1639 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE); 1640 // Draw a point cloud for vertex shader testing, and a single quad for fragment shader testing 1641 if (m_data.stage == STAGE_VERTEX) 1642 { 1643 vk.cmdDraw(*cmdBuffer, DIM*DIM, 1u, 0u, 0u); 1644 } 1645 else 1646 { 1647 vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u); 1648 } 1649 endRenderPass(vk, *cmdBuffer); 1650 } 1651 1652 memBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; 1653 memBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; 1654 vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, VK_PIPELINE_STAGE_TRANSFER_BIT, 1655 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL); 1656 1657 const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeExtent3D(DIM, DIM, 1u), 1658 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u)); 1659 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **copyBuffer, 1u, ©Region); 1660 1661 endCommandBuffer(vk, *cmdBuffer); 1662 1663 submitCommandsAndWait(vk, device, queue, cmdBuffer.get()); 1664 1665 deUint32 *ptr = (deUint32 *)copyBuffer->getAllocation().getHostPtr(); 1666 invalidateMappedMemoryRange(vk, device, copyBuffer->getAllocation().getMemory(), copyBuffer->getAllocation().getOffset(), DIM*DIM*sizeof(deUint32)); 1667 1668 qpTestResult res = QP_TEST_RESULT_PASS; 1669 1670 for (deUint32 i = 0; i < DIM*DIM; ++i) 1671 { 1672 if (ptr[i] != 1) 1673 { 1674 res = QP_TEST_RESULT_FAIL; 1675 } 1676 } 1677 1678 return tcu::TestStatus(res, qpGetTestResultName(res)); 1679 } 1680 1681 } // anonymous 1682 1683 tcu::TestCaseGroup* createDescriptorSetRandomTests (tcu::TestContext& testCtx) 1684 { 1685 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "descriptorset_random", "Randomly-generated desciptor set layouts")); 1686 1687 deUint32 seed = 0; 1688 1689 typedef struct 1690 { 1691 deUint32 count; 1692 const char* name; 1693 const char* description; 1694 } TestGroupCase; 1695 1696 TestGroupCase setsCases[] = 1697 { 1698 { 4, "sets4", "4 descriptor sets" }, 1699 { 8, "sets8", "8 descriptor sets" }, 1700 { 16, "sets16", "16 descriptor sets" }, 1701 { 32, "sets32", "32 descriptor sets" }, 1702 }; 1703 1704 TestGroupCase indexCases[] = 1705 { 1706 { INDEX_TYPE_NONE, "noarray", "all descriptor declarations are not arrays" }, 1707 { INDEX_TYPE_CONSTANT, "constant", "constant indexing of descriptor arrays" }, 1708 { INDEX_TYPE_PUSHCONSTANT, "unifindexed", "indexing descriptor arrays with push constants" }, 1709 { INDEX_TYPE_DEPENDENT, "dynindexed", "dynamically uniform indexing descriptor arrays" }, 1710 { INDEX_TYPE_RUNTIME_SIZE, "runtimesize", "runtime-size declarations of descriptor arrays" }, 1711 }; 1712 1713 TestGroupCase uboCases[] = 1714 { 1715 { 12, "ubolimitlow", "spec minmax ubo limit" }, 1716 { 4096, "ubolimithigh", "high ubo limit" }, 1717 }; 1718 1719 TestGroupCase sboCases[] = 1720 { 1721 { 4, "sbolimitlow", "spec minmax ssbo limit" }, 1722 { 4096, "sbolimithigh", "high ssbo limit" }, 1723 }; 1724 1725 static const struct 1726 { 1727 deUint32 texCount; 1728 deUint32 imgCount; 1729 const char* name; 1730 const char* description; 1731 } imgCases[] = 1732 { 1733 { 16, 4, "imglimitlow", "spec minmax image limit" }, 1734 { 4096, 4096, "imglimithigh", "high image limit" }, 1735 }; 1736 1737 static const struct 1738 { 1739 deUint32 iubCount; 1740 deUint32 iubSize; 1741 const char* name; 1742 const char* description; 1743 } iubCases[] = 1744 { 1745 { 0, 0, "noiub", "no inline_uniform_block" }, 1746 { 4, 256, "iublimitlow", "inline_uniform_block low limit" }, 1747 { 8, 4096, "iublimithigh", "inline_uniform_block high limit" }, 1748 }; 1749 1750 TestGroupCase stageCases[] = 1751 { 1752 { STAGE_COMPUTE, "comp", "compute" }, 1753 { STAGE_FRAGMENT, "frag", "fragment" }, 1754 { STAGE_VERTEX, "vert", "vertex" }, 1755 }; 1756 1757 TestGroupCase uabCases[] = 1758 { 1759 { UPDATE_AFTER_BIND_DISABLED, "nouab", "no update after bind" }, 1760 }; 1761 1762 for (int setsNdx = 0; setsNdx < DE_LENGTH_OF_ARRAY(setsCases); setsNdx++) 1763 { 1764 de::MovePtr<tcu::TestCaseGroup> setsGroup(new tcu::TestCaseGroup(testCtx, setsCases[setsNdx].name, setsCases[setsNdx].description)); 1765 for (int indexNdx = 0; indexNdx < DE_LENGTH_OF_ARRAY(indexCases); indexNdx++) 1766 { 1767 de::MovePtr<tcu::TestCaseGroup> indexGroup(new tcu::TestCaseGroup(testCtx, indexCases[indexNdx].name, indexCases[indexNdx].description)); 1768 for (int uboNdx = 0; uboNdx < DE_LENGTH_OF_ARRAY(uboCases); uboNdx++) 1769 { 1770 de::MovePtr<tcu::TestCaseGroup> uboGroup(new tcu::TestCaseGroup(testCtx, uboCases[uboNdx].name, uboCases[uboNdx].description)); 1771 for (int sboNdx = 0; sboNdx < DE_LENGTH_OF_ARRAY(sboCases); sboNdx++) 1772 { 1773 de::MovePtr<tcu::TestCaseGroup> sboGroup(new tcu::TestCaseGroup(testCtx, sboCases[sboNdx].name, sboCases[sboNdx].description)); 1774 for (int imgNdx = 0; imgNdx < DE_LENGTH_OF_ARRAY(imgCases); imgNdx++) 1775 { 1776 de::MovePtr<tcu::TestCaseGroup> imgGroup(new tcu::TestCaseGroup(testCtx, imgCases[imgNdx].name, imgCases[imgNdx].description)); 1777 for (int iubNdx = 0; iubNdx < DE_LENGTH_OF_ARRAY(iubCases); iubNdx++) 1778 { 1779 de::MovePtr<tcu::TestCaseGroup> iubGroup(new tcu::TestCaseGroup(testCtx, iubCases[iubNdx].name, iubCases[iubNdx].description)); 1780 for (int uabNdx = 0; uabNdx < DE_LENGTH_OF_ARRAY(uabCases); uabNdx++) 1781 { 1782 de::MovePtr<tcu::TestCaseGroup> uabGroup(new tcu::TestCaseGroup(testCtx, uabCases[uabNdx].name, uabCases[uabNdx].description)); 1783 bool updateAfterBind = (UpdateAfterBind)uabCases[uabNdx].count == UPDATE_AFTER_BIND_ENABLED; 1784 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stageCases); stageNdx++) 1785 { 1786 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, stageCases[stageNdx].name, stageCases[stageNdx].description)); 1787 deUint32 numSeeds = (setsCases[setsNdx].count == 4 && uboNdx == 0 && sboNdx == 0 && imgNdx == 0 && iubNdx == 0) ? 10 : 1; 1788 for (deUint32 rnd = 0; rnd < numSeeds; ++rnd) 1789 { 1790 CaseDef c = 1791 { 1792 (IndexType)indexCases[indexNdx].count, // IndexType indexType; 1793 setsCases[setsNdx].count, // deUint32 numDescriptorSets; 1794 uboCases[uboNdx].count, // deUint32 maxPerStageUniformBuffers; 1795 8, // deUint32 maxUniformBuffersDynamic; 1796 sboCases[sboNdx].count, // deUint32 maxPerStageStorageBuffers; 1797 4, // deUint32 maxStorageBuffersDynamic; 1798 imgCases[imgNdx].texCount, // deUint32 maxPerStageSampledImages; 1799 imgCases[imgNdx].imgCount, // deUint32 maxPerStageStorageImages; 1800 iubCases[iubNdx].iubCount, // deUint32 maxInlineUniformBlocks; 1801 iubCases[iubNdx].iubSize, // deUint32 maxInlineUniformBlockSize; 1802 (Stage)stageCases[stageNdx].count, // Stage stage; 1803 (UpdateAfterBind)uabCases[uabNdx].count, // UpdateAfterBind uab; 1804 seed++, // deUint32 seed; 1805 }; 1806 1807 string name = de::toString(rnd); 1808 stageGroup->addChild(new DescriptorSetRandomTestCase(testCtx, name.c_str(), "test", c)); 1809 } 1810 (updateAfterBind ? uabGroup : iubGroup)->addChild(stageGroup.release()); 1811 } 1812 if (updateAfterBind) 1813 { 1814 iubGroup->addChild(uabGroup.release()); 1815 } 1816 } 1817 imgGroup->addChild(iubGroup.release()); 1818 } 1819 sboGroup->addChild(imgGroup.release()); 1820 } 1821 uboGroup->addChild(sboGroup.release()); 1822 } 1823 indexGroup->addChild(uboGroup.release()); 1824 } 1825 setsGroup->addChild(indexGroup.release()); 1826 } 1827 group->addChild(setsGroup.release()); 1828 } 1829 return group.release(); 1830 } 1831 1832 } // BindingModel 1833 } // vkt 1834