1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * Copyright (c) 2016 Imagination Technologies Ltd. 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 Robustness Utilities 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktRobustnessUtil.hpp" 26#include "vktCustomInstancesDevices.hpp" 27#include "vkDefs.hpp" 28#include "vkImageUtil.hpp" 29#include "vkPrograms.hpp" 30#include "vkQueryUtil.hpp" 31#include "vkRefUtil.hpp" 32#include "vkTypeUtil.hpp" 33#include "vkCmdUtil.hpp" 34#include "vkObjUtil.hpp" 35#include "vkSafetyCriticalUtil.hpp" 36#include "tcuCommandLine.hpp" 37#include "vkDeviceUtil.hpp" 38#include "deMath.h" 39#include <iomanip> 40#include <limits> 41#include <sstream> 42 43namespace vkt 44{ 45namespace robustness 46{ 47 48using namespace vk; 49using std::vector; 50using std::string; 51 52Move<VkDevice> createRobustBufferAccessDevice (Context& context, const VkPhysicalDeviceFeatures2* enabledFeatures2) 53{ 54 const float queuePriority = 1.0f; 55 56 // Create a universal queue that supports graphics and compute 57 const VkDeviceQueueCreateInfo queueParams = 58 { 59 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType; 60 DE_NULL, // const void* pNext; 61 0u, // VkDeviceQueueCreateFlags flags; 62 context.getUniversalQueueFamilyIndex(), // deUint32 queueFamilyIndex; 63 1u, // deUint32 queueCount; 64 &queuePriority // const float* pQueuePriorities; 65 }; 66 67 VkPhysicalDeviceFeatures enabledFeatures = context.getDeviceFeatures(); 68 enabledFeatures.robustBufferAccess = true; 69 70 // \note Extensions in core are not explicitly enabled even though 71 // they are in the extension list advertised to tests. 72 const auto& extensionPtrs = context.getDeviceCreationExtensions(); 73 74 void* pNext = (void*)enabledFeatures2; 75#ifdef CTS_USES_VULKANSC 76 VkDeviceObjectReservationCreateInfo memReservationInfo = context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo(); 77 memReservationInfo.pNext = pNext; 78 pNext = &memReservationInfo; 79 80 VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features(); 81 sc10Features.pNext = pNext; 82 pNext = &sc10Features; 83 84 VkPipelineCacheCreateInfo pcCI; 85 std::vector<VkPipelinePoolSize> poolSizes; 86 if (context.getTestContext().getCommandLine().isSubProcess()) 87 { 88 if (context.getResourceInterface()->getCacheDataSize() > 0) 89 { 90 pcCI = 91 { 92 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType; 93 DE_NULL, // const void* pNext; 94 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT | 95 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags; 96 context.getResourceInterface()->getCacheDataSize(), // deUintptr initialDataSize; 97 context.getResourceInterface()->getCacheData() // const void* pInitialData; 98 }; 99 memReservationInfo.pipelineCacheCreateInfoCount = 1; 100 memReservationInfo.pPipelineCacheCreateInfos = &pcCI; 101 } 102 103 poolSizes = context.getResourceInterface()->getPipelinePoolSizes(); 104 if (!poolSizes.empty()) 105 { 106 memReservationInfo.pipelinePoolSizeCount = deUint32(poolSizes.size()); 107 memReservationInfo.pPipelinePoolSizes = poolSizes.data(); 108 } 109 } 110#endif 111 112 const VkDeviceCreateInfo deviceParams = 113 { 114 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType; 115 pNext, // const void* pNext; 116 0u, // VkDeviceCreateFlags flags; 117 1u, // deUint32 queueCreateInfoCount; 118 &queueParams, // const VkDeviceQueueCreateInfo* pQueueCreateInfos; 119 0u, // deUint32 enabledLayerCount; 120 nullptr, // const char* const* ppEnabledLayerNames; 121 de::sizeU32(extensionPtrs), // deUint32 enabledExtensionCount; 122 de::dataOrNull(extensionPtrs), // const char* const* ppEnabledExtensionNames; 123 enabledFeatures2 ? nullptr : &enabledFeatures // const VkPhysicalDeviceFeatures* pEnabledFeatures; 124 }; 125 126 // We are creating a custom device with a potentially large amount of extensions and features enabled, using the default device 127 // as a reference. Some implementations may only enable certain device extensions if some instance extensions are enabled, so in 128 // this case it's important to reuse the context instance when creating the device. 129 const auto& vki = context.getInstanceInterface(); 130 const auto instance = context.getInstance(); 131 const auto physicalDevice = chooseDevice(vki, instance, context.getTestContext().getCommandLine()); 132 133 return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), 134 instance, vki, physicalDevice, &deviceParams); 135} 136 137bool areEqual (float a, float b) 138{ 139 return deFloatAbs(a - b) <= 0.001f; 140} 141 142bool isValueZero (const void* valuePtr, size_t valueSizeInBytes) 143{ 144 const deUint8* bytePtr = reinterpret_cast<const deUint8*>(valuePtr); 145 146 for (size_t i = 0; i < valueSizeInBytes; i++) 147 { 148 if (bytePtr[i] != 0) 149 return false; 150 } 151 152 return true; 153} 154 155bool isValueWithinBuffer (const void* buffer, VkDeviceSize bufferSize, const void* valuePtr, size_t valueSizeInBytes) 156{ 157 const deUint8* byteBuffer = reinterpret_cast<const deUint8*>(buffer); 158 159 if (bufferSize < ((VkDeviceSize)valueSizeInBytes)) 160 return false; 161 162 for (VkDeviceSize i = 0; i <= (bufferSize - valueSizeInBytes); i++) 163 { 164 if (!deMemCmp(&byteBuffer[i], valuePtr, valueSizeInBytes)) 165 return true; 166 } 167 168 return false; 169} 170 171bool isValueWithinBufferOrZero (const void* buffer, VkDeviceSize bufferSize, const void* valuePtr, size_t valueSizeInBytes) 172{ 173 return isValueWithinBuffer(buffer, bufferSize, valuePtr, valueSizeInBytes) || isValueZero(valuePtr, valueSizeInBytes); 174} 175 176template<typename T> 177bool verifyVec4IntegerValues (const void* vecPtr) 178{ 179 const T Tzero = T{0}; 180 const T Tone = T{1}; 181 const T Tmax = std::numeric_limits<T>::max(); 182 183 T values[4]; 184 deMemcpy(values, vecPtr, 4*sizeof(T)); 185 return (values[0] == Tzero && values[1] == Tzero && values[2] == Tzero && 186 (values[3] == Tzero || values[3] == Tone || values[3] == Tmax)); 187} 188 189bool verifyOutOfBoundsVec4 (const void* vecPtr, VkFormat bufferFormat) 190{ 191 if (isUintFormat(bufferFormat)) 192 { 193 if (bufferFormat == VK_FORMAT_R64_UINT) 194 return verifyVec4IntegerValues<deUint64>(vecPtr); 195 return verifyVec4IntegerValues<deUint32>(vecPtr); 196 } 197 else if (isIntFormat(bufferFormat)) 198 { 199 if (bufferFormat == VK_FORMAT_R64_SINT) 200 return verifyVec4IntegerValues<deInt64>(vecPtr); 201 return verifyVec4IntegerValues<deInt32>(vecPtr); 202 } 203 else if (isFloatFormat(bufferFormat)) 204 { 205 const float* data = (float*)vecPtr; 206 207 return areEqual(data[0], 0.0f) 208 && areEqual(data[1], 0.0f) 209 && areEqual(data[2], 0.0f) 210 && (areEqual(data[3], 0.0f) || areEqual(data[3], 1.0f)); 211 } 212 else if (bufferFormat == VK_FORMAT_A2B10G10R10_UNORM_PACK32) 213 { 214 return *((deUint32*)vecPtr) == 0xc0000000u; 215 } 216 217 DE_ASSERT(false); 218 return false; 219} 220 221void populateBufferWithTestValues (void* buffer, VkDeviceSize size, VkFormat format) 222{ 223 // Assign a sequence of 32-bit values 224 for (VkDeviceSize scalarNdx = 0; scalarNdx < size / 4; scalarNdx++) 225 { 226 const deUint32 valueIndex = (deUint32)(2 + scalarNdx); // Do not use 0 or 1 227 228 if (isUintFormat(format)) 229 { 230 reinterpret_cast<deUint32*>(buffer)[scalarNdx] = valueIndex; 231 } 232 else if (isIntFormat(format)) 233 { 234 reinterpret_cast<deInt32*>(buffer)[scalarNdx] = -deInt32(valueIndex); 235 } 236 else if (isFloatFormat(format)) 237 { 238 reinterpret_cast<float*>(buffer)[scalarNdx] = float(valueIndex); 239 } 240 else if (format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) 241 { 242 const deUint32 r = ((valueIndex + 0) & ((2u << 10) - 1u)); 243 const deUint32 g = ((valueIndex + 1) & ((2u << 10) - 1u)); 244 const deUint32 b = ((valueIndex + 2) & ((2u << 10) - 1u)); 245 const deUint32 a = ((valueIndex + 0) & ((2u << 2) - 1u)); 246 247 reinterpret_cast<deUint32*>(buffer)[scalarNdx] = (a << 30) | (b << 20) | (g << 10) | r; 248 } 249 else 250 { 251 DE_ASSERT(false); 252 } 253 } 254} 255 256void logValue (std::ostringstream& logMsg, const void* valuePtr, VkFormat valueFormat, size_t valueSize) 257{ 258 if (isUintFormat(valueFormat)) 259 { 260 logMsg << *reinterpret_cast<const deUint32*>(valuePtr); 261 } 262 else if (isIntFormat(valueFormat)) 263 { 264 logMsg << *reinterpret_cast<const deInt32*>(valuePtr); 265 } 266 else if (isFloatFormat(valueFormat)) 267 { 268 logMsg << *reinterpret_cast<const float*>(valuePtr); 269 } 270 else 271 { 272 const deUint8* bytePtr = reinterpret_cast<const deUint8*>(valuePtr); 273 const std::ios::fmtflags streamFlags = logMsg.flags(); 274 275 logMsg << std::hex; 276 for (size_t i = 0; i < valueSize; i++) 277 { 278 logMsg << " " << (deUint32)bytePtr[i]; 279 } 280 logMsg.flags(streamFlags); 281 } 282} 283 284// TestEnvironment 285 286TestEnvironment::TestEnvironment (Context& context, 287 const DeviceInterface& vk, 288 VkDevice device, 289 VkDescriptorSetLayout descriptorSetLayout, 290 VkDescriptorSet descriptorSet) 291 : m_context (context) 292 , m_device (device) 293 , m_descriptorSetLayout (descriptorSetLayout) 294 , m_descriptorSet (descriptorSet) 295{ 296 // Create command pool 297 { 298 const VkCommandPoolCreateInfo commandPoolParams = 299 { 300 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 301 DE_NULL, // const void* pNext; 302 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags; 303 context.getUniversalQueueFamilyIndex() // deUint32 queueFamilyIndex; 304 }; 305 306 m_commandPool = createCommandPool(vk, m_device, &commandPoolParams); 307 } 308 309 // Create command buffer 310 { 311 const VkCommandBufferAllocateInfo commandBufferAllocateInfo = 312 { 313 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 314 DE_NULL, // const void* pNext; 315 *m_commandPool, // VkCommandPool commandPool; 316 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 317 1u, // deUint32 bufferCount; 318 }; 319 320 m_commandBuffer = allocateCommandBuffer(vk, m_device, &commandBufferAllocateInfo); 321 } 322} 323 324VkCommandBuffer TestEnvironment::getCommandBuffer (void) 325{ 326 return *m_commandBuffer; 327} 328 329// GraphicsEnvironment 330 331GraphicsEnvironment::GraphicsEnvironment (Context& context, 332 const DeviceInterface& vk, 333 VkDevice device, 334 VkDescriptorSetLayout descriptorSetLayout, 335 VkDescriptorSet descriptorSet, 336 const VertexBindings& vertexBindings, 337 const VertexAttributes& vertexAttributes, 338 const DrawConfig& drawConfig, 339 bool testPipelineRobustness) 340 341 : TestEnvironment (context, vk, device, descriptorSetLayout, descriptorSet) 342 , m_renderSize (16, 16) 343 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 344{ 345 const auto& vki = context.getInstanceInterface(); 346 const auto instance = context.getInstance(); 347 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 348 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 349 const VkPhysicalDevice physicalDevice = chooseDevice(vki, instance, context.getTestContext().getCommandLine()); 350 SimpleAllocator memAlloc (vk, m_device, getPhysicalDeviceMemoryProperties(vki, physicalDevice)); 351 352 // Create color image and view 353 { 354 const VkImageCreateInfo colorImageParams = 355 { 356 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 357 DE_NULL, // const void* pNext; 358 0u, // VkImageCreateFlags flags; 359 VK_IMAGE_TYPE_2D, // VkImageType imageType; 360 m_colorFormat, // VkFormat format; 361 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent; 362 1u, // deUint32 mipLevels; 363 1u, // deUint32 arrayLayers; 364 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 365 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 366 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 367 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 368 1u, // deUint32 queueFamilyIndexCount; 369 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 370 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 371 }; 372 373 m_colorImage = createImage(vk, m_device, &colorImageParams); 374 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, m_device, *m_colorImage), MemoryRequirement::Any); 375 VK_CHECK(vk.bindImageMemory(m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 376 377 const VkImageViewCreateInfo colorAttachmentViewParams = 378 { 379 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 380 DE_NULL, // const void* pNext; 381 0u, // VkImageViewCreateFlags flags; 382 *m_colorImage, // VkImage image; 383 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 384 m_colorFormat, // VkFormat format; 385 componentMappingRGBA, // VkComponentMapping components; 386 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 387 }; 388 389 m_colorAttachmentView = createImageView(vk, m_device, &colorAttachmentViewParams); 390 } 391 392 // Create render pass 393 m_renderPass = makeRenderPass(vk, m_device, m_colorFormat); 394 395 // Create framebuffer 396 { 397 const VkFramebufferCreateInfo framebufferParams = 398 { 399 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 400 DE_NULL, // const void* pNext; 401 0u, // VkFramebufferCreateFlags flags; 402 *m_renderPass, // VkRenderPass renderPass; 403 1u, // deUint32 attachmentCount; 404 &m_colorAttachmentView.get(), // const VkImageView* pAttachments; 405 (deUint32)m_renderSize.x(), // deUint32 width; 406 (deUint32)m_renderSize.y(), // deUint32 height; 407 1u // deUint32 layers; 408 }; 409 410 m_framebuffer = createFramebuffer(vk, m_device, &framebufferParams); 411 } 412 413 // Create pipeline layout 414 { 415 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 416 { 417 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 418 DE_NULL, // const void* pNext; 419 0u, // VkPipelineLayoutCreateFlags flags; 420 1u, // deUint32 setLayoutCount; 421 &m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 422 0u, // deUint32 pushConstantRangeCount; 423 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 424 }; 425 426 m_pipelineLayout = createPipelineLayout(vk, m_device, &pipelineLayoutParams); 427 } 428 429 m_vertexShaderModule = createShaderModule(vk, m_device, m_context.getBinaryCollection().get("vertex"), 0); 430 m_fragmentShaderModule = createShaderModule(vk, m_device, m_context.getBinaryCollection().get("fragment"), 0); 431 432 // Create pipeline 433 { 434 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 435 { 436 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 437 DE_NULL, // const void* pNext; 438 0u, // VkPipelineVertexInputStateCreateFlags flags; 439 (deUint32)vertexBindings.size(), // deUint32 vertexBindingDescriptionCount; 440 vertexBindings.data(), // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 441 (deUint32)vertexAttributes.size(), // deUint32 vertexAttributeDescriptionCount; 442 vertexAttributes.data() // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 443 }; 444 445 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize)); 446 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize)); 447 448 const void* pNext = DE_NULL; 449#ifndef CTS_USES_VULKANSC 450 VkPipelineRobustnessCreateInfoEXT pipelineRobustnessInfo = initVulkanStructure(); 451 452 if (testPipelineRobustness) 453 { 454 pipelineRobustnessInfo.storageBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT; 455 pipelineRobustnessInfo.uniformBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT; 456 pipelineRobustnessInfo.vertexInputs = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT; 457 pipelineRobustnessInfo.images = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT; 458 pNext = &pipelineRobustnessInfo; 459 } 460#else 461 DE_UNREF(testPipelineRobustness); 462#endif 463 464 m_graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk 465 m_device, // const VkDevice device 466 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout 467 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule 468 DE_NULL, // const VkShaderModule tessellationControlShaderModule 469 DE_NULL, // const VkShaderModule tessellationEvalShaderModule 470 DE_NULL, // const VkShaderModule geometryShaderModule 471 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule 472 *m_renderPass, // const VkRenderPass renderPass 473 viewports, // const std::vector<VkViewport>& viewports 474 scissors, // const std::vector<VkRect2D>& scissors 475 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology 476 0u, // const deUint32 subpass 477 0u, // const deUint32 patchControlPoints 478 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo 479 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo 480 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo 481 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo 482 DE_NULL, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo 483 DE_NULL, // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo 484 pNext); // void* pNext 485 } 486 487 // Record commands 488 { 489 const VkImageMemoryBarrier imageLayoutBarrier = 490 { 491 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 492 DE_NULL, // const void* pNext; 493 (VkAccessFlags)0, // VkAccessFlags srcAccessMask; 494 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 495 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 496 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 497 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 498 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 499 *m_colorImage, // VkImage image; 500 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 501 }; 502 503 beginCommandBuffer(vk, *m_commandBuffer, 0u); 504 { 505 vk.cmdPipelineBarrier(*m_commandBuffer, 506 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 507 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 508 (VkDependencyFlags)0, 509 0u, DE_NULL, 510 0u, DE_NULL, 511 1u, &imageLayoutBarrier); 512 513 beginRenderPass(vk, *m_commandBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.0f)); 514 { 515 const std::vector<VkDeviceSize> vertexBufferOffsets(drawConfig.vertexBuffers.size(), 0ull); 516 517 vk.cmdBindPipeline(*m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline); 518 vk.cmdBindDescriptorSets(*m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet, 0, DE_NULL); 519 vk.cmdBindVertexBuffers(*m_commandBuffer, 0, (deUint32)drawConfig.vertexBuffers.size(), drawConfig.vertexBuffers.data(), vertexBufferOffsets.data()); 520 521 if (drawConfig.indexBuffer == DE_NULL || drawConfig.indexCount == 0) 522 { 523 vk.cmdDraw(*m_commandBuffer, drawConfig.vertexCount, drawConfig.instanceCount, 0, 0); 524 } 525 else 526 { 527 vk.cmdBindIndexBuffer(*m_commandBuffer, drawConfig.indexBuffer, 0, VK_INDEX_TYPE_UINT32); 528 vk.cmdDrawIndexed(*m_commandBuffer, drawConfig.indexCount, drawConfig.instanceCount, 0, 0, 0); 529 } 530 } 531 endRenderPass(vk, *m_commandBuffer); 532 } 533 endCommandBuffer(vk, *m_commandBuffer); 534 } 535} 536 537// ComputeEnvironment 538 539ComputeEnvironment::ComputeEnvironment (Context& context, 540 const DeviceInterface& vk, 541 VkDevice device, 542 VkDescriptorSetLayout descriptorSetLayout, 543 VkDescriptorSet descriptorSet, 544 bool testPipelineRobustness) 545 546 : TestEnvironment (context, vk, device, descriptorSetLayout, descriptorSet) 547{ 548 // Create pipeline layout 549 { 550 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 551 { 552 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 553 DE_NULL, // const void* pNext; 554 0u, // VkPipelineLayoutCreateFlags flags; 555 1u, // deUint32 setLayoutCount; 556 &m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 557 0u, // deUint32 pushConstantRangeCount; 558 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 559 }; 560 561 m_pipelineLayout = createPipelineLayout(vk, m_device, &pipelineLayoutParams); 562 } 563 564 // Create compute pipeline 565 { 566 m_computeShaderModule = createShaderModule(vk, m_device, m_context.getBinaryCollection().get("compute"), 0); 567 568 const VkPipelineShaderStageCreateInfo computeStageParams = 569 { 570 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 571 DE_NULL, // const void* pNext; 572 0u, // VkPipelineShaderStageCreateFlags flags; 573 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 574 *m_computeShaderModule, // VkShaderModule module; 575 "main", // const char* pName; 576 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 577 }; 578 579 const void* pNext = DE_NULL; 580#ifndef CTS_USES_VULKANSC 581 VkPipelineRobustnessCreateInfoEXT pipelineRobustnessInfo = initVulkanStructure(); 582 583 if (testPipelineRobustness) 584 { 585 pipelineRobustnessInfo.storageBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT; 586 pipelineRobustnessInfo.uniformBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT; 587 pipelineRobustnessInfo.vertexInputs = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT; 588 pipelineRobustnessInfo.images = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT; 589 pNext = &pipelineRobustnessInfo; 590 } 591#else 592 DE_UNREF(testPipelineRobustness); 593#endif 594 595 const VkComputePipelineCreateInfo computePipelineParams = 596 { 597 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 598 pNext, // const void* pNext; 599 0u, // VkPipelineCreateFlags flags; 600 computeStageParams, // VkPipelineShaderStageCreateInfo stage; 601 *m_pipelineLayout, // VkPipelineLayout layout; 602 DE_NULL, // VkPipeline basePipelineHandle; 603 0u // deInt32 basePipelineIndex; 604 }; 605 606 m_computePipeline = createComputePipeline(vk, m_device, DE_NULL, &computePipelineParams); 607 } 608 609 // Record commands 610 { 611 beginCommandBuffer(vk, *m_commandBuffer, 0u); 612 vk.cmdBindPipeline(*m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline); 613 vk.cmdBindDescriptorSets(*m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &m_descriptorSet, 0, DE_NULL); 614 vk.cmdDispatch(*m_commandBuffer, 32, 32, 1); 615 endCommandBuffer(vk, *m_commandBuffer); 616 } 617} 618 619} // robustness 620} // vkt 621