318b33800fa6626d2a30f1061ff0369965e403ff
[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, VkInstance instance, const InstanceInterface& vki, 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         const VkPhysicalDevice                  physicalDevice = chooseDevice(vki, instance, context.getTestContext().getCommandLine());
152
153         return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(),
154                                                           instance, vki, physicalDevice, &deviceParams);
155 }
156
157 bool areEqual (float a, float b)
158 {
159         return deFloatAbs(a - b) <= 0.001f;
160 }
161
162 bool isValueZero (const void* valuePtr, size_t valueSizeInBytes)
163 {
164         const deUint8* bytePtr = reinterpret_cast<const deUint8*>(valuePtr);
165
166         for (size_t i = 0; i < valueSizeInBytes; i++)
167         {
168                 if (bytePtr[i] != 0)
169                         return false;
170         }
171
172         return true;
173 }
174
175 bool isValueWithinBuffer (const void* buffer, VkDeviceSize bufferSize, const void* valuePtr, size_t valueSizeInBytes)
176 {
177         const deUint8* byteBuffer = reinterpret_cast<const deUint8*>(buffer);
178
179         if (bufferSize < ((VkDeviceSize)valueSizeInBytes))
180                 return false;
181
182         for (VkDeviceSize i = 0; i <= (bufferSize - valueSizeInBytes); i++)
183         {
184                 if (!deMemCmp(&byteBuffer[i], valuePtr, valueSizeInBytes))
185                         return true;
186         }
187
188         return false;
189 }
190
191 bool isValueWithinBufferOrZero (const void* buffer, VkDeviceSize bufferSize, const void* valuePtr, size_t valueSizeInBytes)
192 {
193         return isValueWithinBuffer(buffer, bufferSize, valuePtr, valueSizeInBytes) || isValueZero(valuePtr, valueSizeInBytes);
194 }
195
196 template<typename T>
197 bool verifyVec4IntegerValues (const void* vecPtr)
198 {
199         const T Tzero   = T{0};
200         const T Tone    = T{1};
201         const T Tmax    = std::numeric_limits<T>::max();
202
203         T values[4];
204         deMemcpy(values, vecPtr, 4*sizeof(T));
205         return (values[0] == Tzero && values[1] == Tzero && values[2] == Tzero &&
206                     (values[3] == Tzero || values[3] == Tone || values[3] == Tmax));
207 }
208
209 bool verifyOutOfBoundsVec4 (const void* vecPtr, VkFormat bufferFormat)
210 {
211         if (isUintFormat(bufferFormat))
212         {
213                 if (bufferFormat == VK_FORMAT_R64_UINT)
214                         return verifyVec4IntegerValues<deUint64>(vecPtr);
215                 return verifyVec4IntegerValues<deUint32>(vecPtr);
216         }
217         else if (isIntFormat(bufferFormat))
218         {
219                 if (bufferFormat == VK_FORMAT_R64_SINT)
220                         return verifyVec4IntegerValues<deInt64>(vecPtr);
221                 return verifyVec4IntegerValues<deInt32>(vecPtr);
222         }
223         else if (isFloatFormat(bufferFormat))
224         {
225                 const float* data = (float*)vecPtr;
226
227                 return areEqual(data[0], 0.0f)
228                         && areEqual(data[1], 0.0f)
229                         && areEqual(data[2], 0.0f)
230                         && (areEqual(data[3], 0.0f) || areEqual(data[3], 1.0f));
231         }
232         else if (bufferFormat == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
233         {
234                 return *((deUint32*)vecPtr) == 0xc0000000u;
235         }
236
237         DE_ASSERT(false);
238         return false;
239 }
240
241 void populateBufferWithTestValues (void* buffer, VkDeviceSize size, VkFormat format)
242 {
243         // Assign a sequence of 32-bit values
244         for (VkDeviceSize scalarNdx = 0; scalarNdx < size / 4; scalarNdx++)
245         {
246                 const deUint32 valueIndex = (deUint32)(2 + scalarNdx); // Do not use 0 or 1
247
248                 if (isUintFormat(format))
249                 {
250                         reinterpret_cast<deUint32*>(buffer)[scalarNdx] = valueIndex;
251                 }
252                 else if (isIntFormat(format))
253                 {
254                         reinterpret_cast<deInt32*>(buffer)[scalarNdx] = -deInt32(valueIndex);
255                 }
256                 else if (isFloatFormat(format))
257                 {
258                         reinterpret_cast<float*>(buffer)[scalarNdx] = float(valueIndex);
259                 }
260                 else if (format == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
261                 {
262                         const deUint32  r       = ((valueIndex + 0) & ((2u << 10) - 1u));
263                         const deUint32  g       = ((valueIndex + 1) & ((2u << 10) - 1u));
264                         const deUint32  b       = ((valueIndex + 2) & ((2u << 10) - 1u));
265                         const deUint32  a       = ((valueIndex + 0) & ((2u << 2) - 1u));
266
267                         reinterpret_cast<deUint32*>(buffer)[scalarNdx] = (a << 30) | (b << 20) | (g << 10) | r;
268                 }
269                 else
270                 {
271                         DE_ASSERT(false);
272                 }
273         }
274 }
275
276 void logValue (std::ostringstream& logMsg, const void* valuePtr, VkFormat valueFormat, size_t valueSize)
277 {
278         if (isUintFormat(valueFormat))
279         {
280                 logMsg << *reinterpret_cast<const deUint32*>(valuePtr);
281         }
282         else if (isIntFormat(valueFormat))
283         {
284                 logMsg << *reinterpret_cast<const deInt32*>(valuePtr);
285         }
286         else if (isFloatFormat(valueFormat))
287         {
288                 logMsg << *reinterpret_cast<const float*>(valuePtr);
289         }
290         else
291         {
292                 const deUint8*                          bytePtr         = reinterpret_cast<const deUint8*>(valuePtr);
293                 const std::ios::fmtflags        streamFlags     = logMsg.flags();
294
295                 logMsg << std::hex;
296                 for (size_t i = 0; i < valueSize; i++)
297                 {
298                         logMsg << " " << (deUint32)bytePtr[i];
299                 }
300                 logMsg.flags(streamFlags);
301         }
302 }
303
304 // TestEnvironment
305
306 TestEnvironment::TestEnvironment (Context&                                      context,
307                                                                   VkInstance                            instance,
308                                                                   const InstanceInterface&      instanceInterface,
309                                                                   VkDevice                                      device,
310                                                                   VkDescriptorSetLayout         descriptorSetLayout,
311                                                                   VkDescriptorSet                       descriptorSet)
312         : m_context                             (context)
313         , m_instance                    (instance)
314         , m_instanceInterface   (instanceInterface)
315         , m_device                              (device)
316         , m_descriptorSetLayout (descriptorSetLayout)
317         , m_descriptorSet               (descriptorSet)
318 {
319         const DeviceInterface& vk = context.getDeviceInterface();
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                                                                                   VkInstance                            instance,
358                                                                                   const InstanceInterface&      instanceInterface,
359                                                                                   VkDevice                                      device,
360                                                                                   VkDescriptorSetLayout         descriptorSetLayout,
361                                                                                   VkDescriptorSet                       descriptorSet,
362                                                                                   const VertexBindings&         vertexBindings,
363                                                                                   const VertexAttributes&       vertexAttributes,
364                                                                                   const DrawConfig&                     drawConfig,
365                                                                                   bool                                          testPipelineRobustness)
366
367         : TestEnvironment               (context, instance, instanceInterface, device, descriptorSetLayout, descriptorSet)
368         , m_renderSize                  (16, 16)
369         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
370 {
371         const DeviceInterface&          vk                                              = context.getDeviceInterface();
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(m_instanceInterface, instance, context.getTestContext().getCommandLine());
375         SimpleAllocator                         memAlloc                                (vk, m_device, getPhysicalDeviceMemoryProperties(m_instanceInterface, 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                                                                                 VkInstance                                      instance,
566                                                                                 const InstanceInterface&        instanceInterface,
567                                                                                 VkDevice                                        device,
568                                                                                 VkDescriptorSetLayout           descriptorSetLayout,
569                                                                                 VkDescriptorSet                         descriptorSet,
570                                                                                 bool                                            testPipelineRobustness)
571
572         : TestEnvironment       (context, instance, instanceInterface, device, descriptorSetLayout, descriptorSet)
573 {
574         const DeviceInterface& vk = context.getDeviceInterface();
575
576         // Create pipeline layout
577         {
578                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
579                 {
580                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                  // VkStructureType                                      sType;
581                         DE_NULL,                                                                                                // const void*                                          pNext;
582                         0u,                                                                                                             // VkPipelineLayoutCreateFlags          flags;
583                         1u,                                                                                                             // deUint32                                                     setLayoutCount;
584                         &m_descriptorSetLayout,                                                                 // const VkDescriptorSetLayout*         pSetLayouts;
585                         0u,                                                                                                             // deUint32                                                     pushConstantRangeCount;
586                         DE_NULL                                                                                                 // const VkPushConstantRange*           pPushConstantRanges;
587                 };
588
589                 m_pipelineLayout = createPipelineLayout(vk, m_device, &pipelineLayoutParams);
590         }
591
592         // Create compute pipeline
593         {
594                 m_computeShaderModule = createShaderModule(vk, m_device, m_context.getBinaryCollection().get("compute"), 0);
595
596                 const VkPipelineShaderStageCreateInfo computeStageParams =
597                 {
598                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
599                         DE_NULL,                                                                                                // const void*                                                  pNext;
600                         0u,                                                                                                             // VkPipelineShaderStageCreateFlags             flags;
601                         VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                                stage;
602                         *m_computeShaderModule,                                                                 // VkShaderModule                                               module;
603                         "main",                                                                                                 // const char*                                                  pName;
604                         DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
605                 };
606
607                 const void* pNext = DE_NULL;
608 #ifndef CTS_USES_VULKANSC
609                 VkPipelineRobustnessCreateInfoEXT pipelineRobustnessInfo = initVulkanStructure();
610
611                 if (testPipelineRobustness)
612                 {
613                         pipelineRobustnessInfo.storageBuffers   = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT;
614                         pipelineRobustnessInfo.uniformBuffers   = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT;
615                         pipelineRobustnessInfo.vertexInputs             = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT;
616                         pipelineRobustnessInfo.images                   = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT;
617                         pNext                                                                   = &pipelineRobustnessInfo;
618                 }
619 #else
620                 DE_UNREF(testPipelineRobustness);
621 #endif
622
623                 const VkComputePipelineCreateInfo computePipelineParams =
624                 {
625                         VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                         // VkStructureType                                              sType;
626                         pNext,                                                                                                          // const void*                                                  pNext;
627                         0u,                                                                                                                     // VkPipelineCreateFlags                                flags;
628                         computeStageParams,                                                                                     // VkPipelineShaderStageCreateInfo              stage;
629                         *m_pipelineLayout,                                                                                      // VkPipelineLayout                                             layout;
630                         DE_NULL,                                                                                                        // VkPipeline                                                   basePipelineHandle;
631                         0u                                                                                                                      // deInt32                                                              basePipelineIndex;
632                 };
633
634                 m_computePipeline = createComputePipeline(vk, m_device, DE_NULL, &computePipelineParams);
635         }
636
637         // Record commands
638         {
639                 beginCommandBuffer(vk, *m_commandBuffer, 0u);
640                 vk.cmdBindPipeline(*m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
641                 vk.cmdBindDescriptorSets(*m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &m_descriptorSet, 0, DE_NULL);
642                 vk.cmdDispatch(*m_commandBuffer, 32, 32, 1);
643                 endCommandBuffer(vk, *m_commandBuffer);
644         }
645 }
646
647 } // robustness
648 } // vkt