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