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
removeExtensions(const vector<string> & a,const vector<const char * > & b)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
createRobustBufferAccessDevice(Context & context,const VkPhysicalDeviceFeatures2 * enabledFeatures2)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
areEqual(float a,float b)162 bool areEqual (float a, float b)
163 {
164 return deFloatAbs(a - b) <= 0.001f;
165 }
166
isValueZero(const void * valuePtr,size_t valueSizeInBytes)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
isValueWithinBuffer(const void * buffer,VkDeviceSize bufferSize,const void * valuePtr,size_t valueSizeInBytes)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
isValueWithinBufferOrZero(const void * buffer,VkDeviceSize bufferSize,const void * valuePtr,size_t valueSizeInBytes)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>
verifyVec4IntegerValues(const void * vecPtr)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
verifyOutOfBoundsVec4(const void * vecPtr,VkFormat bufferFormat)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
populateBufferWithTestValues(void * buffer,VkDeviceSize size,VkFormat format)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
logValue(std::ostringstream & logMsg,const void * valuePtr,VkFormat valueFormat,size_t valueSize)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
TestEnvironment(Context & context,const DeviceInterface & vk,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorSet descriptorSet)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
getCommandBuffer(void)349 VkCommandBuffer TestEnvironment::getCommandBuffer (void)
350 {
351 return *m_commandBuffer;
352 }
353
354 // GraphicsEnvironment
355
GraphicsEnvironment(Context & context,const DeviceInterface & vk,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorSet descriptorSet,const VertexBindings & vertexBindings,const VertexAttributes & vertexAttributes,const DrawConfig & drawConfig,bool testPipelineRobustness)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
ComputeEnvironment(Context & context,const DeviceInterface & vk,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorSet descriptorSet,bool testPipelineRobustness)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
646